Skip to content

Commit 9212d1d

Browse files
committed
Support arbitrary inner type in NamedImplKey.
Before this commit `NamedImplKey` could only represent the inner type as `rust: &'a Ident`. For example, it could represent `Vec<Foo>` but could not represent `Vec<Box<Foo>>` where the inner type (`Box<Foo>` in our example) is not a simple identifier. After this commit `NamedImplKey` is refactored to support an arbitrary inner type. Note that (to simplify and to minimize risks associated with this commit) this new ability is not actually used at this point - it is planned to be used in follow-up commits to incrementally relax generic type argument restrictions in `syntax/check.rs`. This commit is quite big, but it seems difficult to extract some changes to smaller, separate commits, because all of the changes stem from the refactoring of the `NamedImplKey`. At a high-level this commit contains the following changes: 1. `syntax/instantiate.rs`: Changing `pub rust: &'a Ident` field of `NamedImplKey` to `pub inner: &'a Type`. This is the main/root change in this commit. 2. `gen/src/write.rs`: supporting arbitrary inner types when writing C++ thunks exposing instantiations/monomorphizations of templates/generics supported by `cxx`. * This depends on `fn stringify_type` introduced in `gen/src/write.rs` in an earlier commit. * Handling arbitrary inner types *in general* means that we can delete `enum UniquePtr` which provided handling of two *specific* inner types. 3. `macro/src/expand.rs`: supporting arbitrary inner types when writing Rust thunks exposing instantiations/monomorphizations of templates/generics supported by `cxx`. * Using `#inner` instead of `#ident` may now (optionally) cover generic lifetime arguments. This is why this commit also changes `macro/src/generics.rs`. And this is why we can no longer need the `ty_generics` field from `struct Impl`. * One minor functional change here is changing the error messages so that references to type names are generated purely in the generated bindings, without depending on `fn display_namespaced`. 4. `syntax/mangle.rs`: supporting mangling of individual types. This helps to: * Support the (long-term, not-yet-realized) high-level goal of actually allowing and using arbitrary inner types * Deduplicate mangling code details that were somewhat duplicated in `macro/src/expand.rs` and `gen/src/write.rs`. 5. `syntax/types.rs`: Supporting arbitrary inner types in * `fn is_maybe_trivial` * `fn is_local` (this function supports an earlier refactoring that changed how `cxx` decides whether to provide an *implicit* impl of a given generic/template instantiation/monomorphization)
1 parent a4d5ac8 commit 9212d1d

File tree

13 files changed

+313
-318
lines changed

13 files changed

+313
-318
lines changed

gen/src/write.rs

Lines changed: 28 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@ use crate::syntax::map::UnorderedMap as Map;
1010
use crate::syntax::namespace::Namespace;
1111
use crate::syntax::primitive::{self, PrimitiveKind};
1212
use crate::syntax::set::UnorderedSet;
13-
use crate::syntax::symbol::{self, Symbol};
13+
use crate::syntax::symbol::Symbol;
1414
use crate::syntax::trivial::{self, TrivialReason};
1515
use crate::syntax::{
1616
derive, mangle, Api, Doc, Enum, ExternFn, ExternType, FnKind, Lang, Pair, Signature, Struct,
1717
Trait, Type, TypeAlias, Types, Var,
1818
};
19-
use proc_macro2::Ident;
2019

2120
pub(super) fn gen(apis: &[Api], types: &Types, opt: &Opt, header: bool) -> Vec<u8> {
2221
let mut out_file = OutFile::new(header, opt, types);
@@ -1573,57 +1572,6 @@ fn write_space_after_type_to_generic_writer(
15731572
}
15741573
}
15751574

1576-
#[derive(Copy, Clone)]
1577-
enum UniquePtr<'a> {
1578-
Ident(&'a Ident),
1579-
CxxVector(&'a Ident),
1580-
}
1581-
1582-
// TODO(@anforowicz): Replace `trait ToTypename` with `stringify_type`.
1583-
trait ToTypename {
1584-
/// Formats `self` using C++ syntax. For example, if `self` represents `UniquePtr<u32>`,
1585-
/// then it will be formatted as `::std::unique_ptr<uint32_t>`.
1586-
fn to_typename(&self, types: &Types) -> String;
1587-
}
1588-
1589-
impl ToTypename for Ident {
1590-
fn to_typename(&self, types: &Types) -> String {
1591-
types.resolve(self).name.to_fully_qualified()
1592-
}
1593-
}
1594-
1595-
impl<'a> ToTypename for UniquePtr<'a> {
1596-
fn to_typename(&self, types: &Types) -> String {
1597-
match self {
1598-
UniquePtr::Ident(ident) => ident.to_typename(types),
1599-
UniquePtr::CxxVector(element) => {
1600-
format!("::std::vector<{}>", element.to_typename(types))
1601-
}
1602-
}
1603-
}
1604-
}
1605-
1606-
trait ToMangled {
1607-
fn to_mangled(&self, types: &Types) -> Symbol;
1608-
}
1609-
1610-
impl ToMangled for Ident {
1611-
fn to_mangled(&self, types: &Types) -> Symbol {
1612-
types.resolve(self).name.to_symbol()
1613-
}
1614-
}
1615-
1616-
impl<'a> ToMangled for UniquePtr<'a> {
1617-
fn to_mangled(&self, types: &Types) -> Symbol {
1618-
match self {
1619-
UniquePtr::Ident(ident) => ident.to_mangled(types),
1620-
UniquePtr::CxxVector(element) => {
1621-
symbol::join(&[&"std", &"vector", &element.to_mangled(types)])
1622-
}
1623-
}
1624-
}
1625-
}
1626-
16271575
fn write_generic_instantiations(out: &mut OutFile) {
16281576
if out.header {
16291577
return;
@@ -1659,9 +1607,8 @@ fn write_generic_instantiations(out: &mut OutFile) {
16591607
}
16601608

16611609
fn write_rust_box_extern(out: &mut OutFile, key: &NamedImplKey) {
1662-
let resolve = out.types.resolve(key);
1663-
let inner = resolve.name.to_fully_qualified();
1664-
let instance = resolve.name.to_symbol();
1610+
let inner = stringify_type(key.inner, out.types);
1611+
let instance = &key.symbol;
16651612

16661613
out.pragma.dollar_in_identifier = true;
16671614

@@ -1683,9 +1630,8 @@ fn write_rust_box_extern(out: &mut OutFile, key: &NamedImplKey) {
16831630
}
16841631

16851632
fn write_rust_vec_extern(out: &mut OutFile, key: &NamedImplKey) {
1686-
let element = key.rust;
1687-
let inner = element.to_typename(out.types);
1688-
let instance = element.to_mangled(out.types);
1633+
let inner = stringify_type(key.inner, out.types);
1634+
let instance = &key.symbol;
16891635

16901636
out.include.cstddef = true;
16911637
out.pragma.dollar_in_identifier = true;
@@ -1733,9 +1679,8 @@ fn write_rust_vec_extern(out: &mut OutFile, key: &NamedImplKey) {
17331679
}
17341680

17351681
fn write_rust_box_impl(out: &mut OutFile, key: &NamedImplKey) {
1736-
let resolve = out.types.resolve(key);
1737-
let inner = resolve.name.to_fully_qualified();
1738-
let instance = resolve.name.to_symbol();
1682+
let inner = stringify_type(key.inner, out.types);
1683+
let instance = &key.symbol;
17391684

17401685
out.pragma.dollar_in_identifier = true;
17411686

@@ -1767,9 +1712,8 @@ fn write_rust_box_impl(out: &mut OutFile, key: &NamedImplKey) {
17671712
}
17681713

17691714
fn write_rust_vec_impl(out: &mut OutFile, key: &NamedImplKey) {
1770-
let element = key.rust;
1771-
let inner = element.to_typename(out.types);
1772-
let instance = element.to_mangled(out.types);
1715+
let inner = stringify_type(key.inner, out.types);
1716+
let instance = &key.symbol;
17731717

17741718
out.include.cstddef = true;
17751719
out.pragma.dollar_in_identifier = true;
@@ -1856,28 +1800,25 @@ fn write_rust_vec_impl(out: &mut OutFile, key: &NamedImplKey) {
18561800
}
18571801

18581802
fn write_unique_ptr(out: &mut OutFile, key: &NamedImplKey) {
1859-
let ty = UniquePtr::Ident(key.rust);
1860-
write_unique_ptr_common(out, ty);
1803+
write_unique_ptr_common(out, key.inner);
18611804
}
18621805

18631806
// Shared by UniquePtr<T> and UniquePtr<CxxVector<T>>.
1864-
fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
1807+
fn write_unique_ptr_common(out: &mut OutFile, ty: &Type) {
18651808
out.include.new = true;
18661809
out.include.utility = true;
18671810
out.pragma.dollar_in_identifier = true;
18681811
out.pragma.missing_declarations = true;
18691812

1870-
let inner = ty.to_typename(out.types);
1871-
let instance = ty.to_mangled(out.types);
1813+
let inner = stringify_type(ty, out.types);
1814+
let instance = crate::syntax::mangle::type_(ty)
1815+
.expect("Earlier syntax/check.rs checks should filter out non-mangle-able types");
18721816

1873-
let can_construct_from_value = match ty {
1874-
// Some aliases are to opaque types; some are to trivial types. We can't
1875-
// know at code generation time, so we generate both C++ and Rust side
1876-
// bindings for a "new" method anyway. But the Rust code can't be called
1877-
// for Opaque types because the 'new' method is not implemented.
1878-
UniquePtr::Ident(ident) => out.types.is_maybe_trivial(ident),
1879-
UniquePtr::CxxVector(_) => false,
1880-
};
1817+
// Some aliases are to opaque types; some are to trivial types. We can't
1818+
// know at code generation time, so we generate both C++ and Rust side
1819+
// bindings for a "new" method anyway. But the Rust code can't be called
1820+
// for Opaque types because the 'new' method is not implemented.
1821+
let can_construct_from_value = out.types.is_maybe_trivial(ty);
18811822

18821823
out.builtin.is_complete = true;
18831824
writeln!(
@@ -1966,10 +1907,8 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
19661907
}
19671908

19681909
fn write_shared_ptr(out: &mut OutFile, key: &NamedImplKey) {
1969-
let ident = key.rust;
1970-
let resolve = out.types.resolve(ident);
1971-
let inner = resolve.name.to_fully_qualified();
1972-
let instance = resolve.name.to_symbol();
1910+
let inner = stringify_type(key.inner, out.types);
1911+
let instance = &key.symbol;
19731912

19741913
out.include.new = true;
19751914
out.include.utility = true;
@@ -1980,7 +1919,7 @@ fn write_shared_ptr(out: &mut OutFile, key: &NamedImplKey) {
19801919
// know at code generation time, so we generate both C++ and Rust side
19811920
// bindings for a "new" method anyway. But the Rust code can't be called for
19821921
// Opaque types because the 'new' method is not implemented.
1983-
let can_construct_from_value = out.types.is_maybe_trivial(ident);
1922+
let can_construct_from_value = out.types.is_maybe_trivial(key.inner);
19841923

19851924
writeln!(
19861925
out,
@@ -2064,9 +2003,8 @@ fn write_shared_ptr(out: &mut OutFile, key: &NamedImplKey) {
20642003
}
20652004

20662005
fn write_weak_ptr(out: &mut OutFile, key: &NamedImplKey) {
2067-
let resolve = out.types.resolve(key);
2068-
let inner = resolve.name.to_fully_qualified();
2069-
let instance = resolve.name.to_symbol();
2006+
let inner = stringify_type(key.inner, out.types);
2007+
let instance = &key.symbol;
20702008

20712009
out.include.new = true;
20722010
out.include.utility = true;
@@ -2135,9 +2073,8 @@ fn write_weak_ptr(out: &mut OutFile, key: &NamedImplKey) {
21352073
}
21362074

21372075
fn write_cxx_vector(out: &mut OutFile, key: &NamedImplKey) {
2138-
let element = key.rust;
2139-
let inner = element.to_typename(out.types);
2140-
let instance = element.to_mangled(out.types);
2076+
let inner = stringify_type(key.inner, out.types);
2077+
let instance = &key.symbol;
21412078

21422079
out.include.cstddef = true;
21432080
out.include.utility = true;
@@ -2195,7 +2132,7 @@ fn write_cxx_vector(out: &mut OutFile, key: &NamedImplKey) {
21952132
);
21962133
writeln!(out, "}}");
21972134

2198-
if out.types.is_maybe_trivial(element) {
2135+
if out.types.is_maybe_trivial(key.inner) {
21992136
begin_function_definition(out);
22002137
writeln!(
22012138
out,
@@ -2218,5 +2155,5 @@ fn write_cxx_vector(out: &mut OutFile, key: &NamedImplKey) {
22182155
}
22192156

22202157
out.include.memory = true;
2221-
write_unique_ptr_common(out, UniquePtr::CxxVector(element));
2158+
write_unique_ptr_common(out, key.outer);
22222159
}

0 commit comments

Comments
 (0)