Track the angle brackets attached to generic implicit impls
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 7b0b49b..406018a 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -3,7 +3,7 @@
use crate::gen::out::OutFile;
use crate::gen::{builtin, include, Opt};
use crate::syntax::atom::Atom::{self, *};
-use crate::syntax::instantiate::ImplKey;
+use crate::syntax::instantiate::{ImplKey, NamedImplKey};
use crate::syntax::map::UnorderedMap as Map;
use crate::syntax::set::UnorderedSet;
use crate::syntax::symbol::Symbol;
@@ -1349,7 +1349,7 @@
out.begin_block(Block::ExternC);
for impl_key in out.types.impls.keys() {
out.next_section();
- match impl_key {
+ match *impl_key {
ImplKey::RustBox(ident) => write_rust_box_extern(out, ident),
ImplKey::RustVec(ident) => write_rust_vec_extern(out, ident),
ImplKey::UniquePtr(ident) => write_unique_ptr(out, ident),
@@ -1363,7 +1363,7 @@
out.begin_block(Block::Namespace("rust"));
out.begin_block(Block::InlineNamespace("cxxbridge1"));
for impl_key in out.types.impls.keys() {
- match impl_key {
+ match *impl_key {
ImplKey::RustBox(ident) => write_rust_box_impl(out, ident),
ImplKey::RustVec(ident) => write_rust_vec_impl(out, ident),
_ => {}
@@ -1373,7 +1373,8 @@
out.end_block(Block::Namespace("rust"));
}
-fn write_rust_box_extern(out: &mut OutFile, ident: &Ident) {
+fn write_rust_box_extern(out: &mut OutFile, key: NamedImplKey) {
+ let ident = key.rust;
let resolve = out.types.resolve(ident);
let inner = resolve.name.to_fully_qualified();
let instance = resolve.name.to_symbol();
@@ -1395,7 +1396,8 @@
);
}
-fn write_rust_vec_extern(out: &mut OutFile, element: &Ident) {
+fn write_rust_vec_extern(out: &mut OutFile, key: NamedImplKey) {
+ let element = key.rust;
let inner = element.to_typename(out.types);
let instance = element.to_mangled(out.types);
@@ -1438,7 +1440,8 @@
);
}
-fn write_rust_box_impl(out: &mut OutFile, ident: &Ident) {
+fn write_rust_box_impl(out: &mut OutFile, key: NamedImplKey) {
+ let ident = key.rust;
let resolve = out.types.resolve(ident);
let inner = resolve.name.to_fully_qualified();
let instance = resolve.name.to_symbol();
@@ -1470,7 +1473,8 @@
writeln!(out, "}}");
}
-fn write_rust_vec_impl(out: &mut OutFile, element: &Ident) {
+fn write_rust_vec_impl(out: &mut OutFile, key: NamedImplKey) {
+ let element = key.rust;
let inner = element.to_typename(out.types);
let instance = element.to_mangled(out.types);
@@ -1547,8 +1551,8 @@
writeln!(out, "}}");
}
-fn write_unique_ptr(out: &mut OutFile, ident: &Ident) {
- let ty = UniquePtr::Ident(ident);
+fn write_unique_ptr(out: &mut OutFile, key: NamedImplKey) {
+ let ty = UniquePtr::Ident(key.rust);
write_unique_ptr_common(out, ty);
}
@@ -1663,7 +1667,8 @@
writeln!(out, "}}");
}
-fn write_shared_ptr(out: &mut OutFile, ident: &Ident) {
+fn write_shared_ptr(out: &mut OutFile, key: NamedImplKey) {
+ let ident = key.rust;
let resolve = out.types.resolve(ident);
let inner = resolve.name.to_fully_qualified();
let instance = resolve.name.to_symbol();
@@ -1735,7 +1740,8 @@
writeln!(out, "}}");
}
-fn write_weak_ptr(out: &mut OutFile, ident: &Ident) {
+fn write_weak_ptr(out: &mut OutFile, key: NamedImplKey) {
+ let ident = key.rust;
let resolve = out.types.resolve(ident);
let inner = resolve.name.to_fully_qualified();
let instance = resolve.name.to_symbol();
@@ -1794,7 +1800,8 @@
writeln!(out, "}}");
}
-fn write_cxx_vector(out: &mut OutFile, element: &Ident) {
+fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) {
+ let element = key.rust;
let inner = element.to_typename(out.types);
let instance = element.to_mangled(out.types);
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 700958c..c68c13d 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -1,7 +1,7 @@
use crate::syntax::atom::Atom::*;
use crate::syntax::attrs::{self, OtherAttrs};
use crate::syntax::file::Module;
-use crate::syntax::instantiate::ImplKey;
+use crate::syntax::instantiate::{ImplKey, NamedImplKey};
use crate::syntax::qualified::QualifiedName;
use crate::syntax::report::Errors;
use crate::syntax::symbol::Symbol;
@@ -85,7 +85,7 @@
}
for (impl_key, &explicit_impl) in &types.impls {
- match impl_key {
+ match *impl_key {
ImplKey::RustBox(ident) => {
hidden.extend(expand_rust_box(ident, types, explicit_impl));
}
@@ -1125,7 +1125,8 @@
crate::type_id::expand(Crate::Cxx, qualified)
}
-fn expand_rust_box(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream {
+fn expand_rust_box(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream {
+ let ident = key.rust;
let resolve = types.resolve(ident);
let link_prefix = format!("cxxbridge1$box${}$", resolve.name.to_symbol());
let link_alloc = format!("{}alloc", link_prefix);
@@ -1165,7 +1166,8 @@
}
}
-fn expand_rust_vec(elem: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream {
+fn expand_rust_vec(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream {
+ let elem = key.rust;
let resolve = types.resolve(elem);
let link_prefix = format!("cxxbridge1$rust_vec${}$", resolve.name.to_symbol());
let link_new = format!("{}new", link_prefix);
@@ -1233,7 +1235,12 @@
}
}
-fn expand_unique_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream {
+fn expand_unique_ptr(
+ key: NamedImplKey,
+ types: &Types,
+ explicit_impl: Option<&Impl>,
+) -> TokenStream {
+ let ident = key.rust;
let name = ident.to_string();
let resolve = types.resolve(ident);
let prefix = format!("cxxbridge1$unique_ptr${}$", resolve.name.to_symbol());
@@ -1326,7 +1333,12 @@
}
}
-fn expand_shared_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream {
+fn expand_shared_ptr(
+ key: NamedImplKey,
+ types: &Types,
+ explicit_impl: Option<&Impl>,
+) -> TokenStream {
+ let ident = key.rust;
let name = ident.to_string();
let resolve = types.resolve(ident);
let prefix = format!("cxxbridge1$shared_ptr${}$", resolve.name.to_symbol());
@@ -1404,7 +1416,8 @@
}
}
-fn expand_weak_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream {
+fn expand_weak_ptr(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream {
+ let ident = key.rust;
let name = ident.to_string();
let resolve = types.resolve(ident);
let prefix = format!("cxxbridge1$weak_ptr${}$", resolve.name.to_symbol());
@@ -1471,7 +1484,12 @@
}
}
-fn expand_cxx_vector(elem: &Ident, explicit_impl: Option<&Impl>, types: &Types) -> TokenStream {
+fn expand_cxx_vector(
+ key: NamedImplKey,
+ explicit_impl: Option<&Impl>,
+ types: &Types,
+) -> TokenStream {
+ let elem = key.rust;
let name = elem.to_string();
let resolve = types.resolve(elem);
let prefix = format!("cxxbridge1$std$vector${}$", resolve.name.to_symbol());
diff --git a/syntax/instantiate.rs b/syntax/instantiate.rs
index e9c6f29..c2a5af0 100644
--- a/syntax/instantiate.rs
+++ b/syntax/instantiate.rs
@@ -1,43 +1,76 @@
-use crate::syntax::Type;
+use crate::syntax::{NamedType, Type};
use proc_macro2::Ident;
+use std::hash::{Hash, Hasher};
+use syn::Token;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum ImplKey<'a> {
- RustBox(&'a Ident),
- RustVec(&'a Ident),
- UniquePtr(&'a Ident),
- SharedPtr(&'a Ident),
- WeakPtr(&'a Ident),
- CxxVector(&'a Ident),
+ RustBox(NamedImplKey<'a>),
+ RustVec(NamedImplKey<'a>),
+ UniquePtr(NamedImplKey<'a>),
+ SharedPtr(NamedImplKey<'a>),
+ WeakPtr(NamedImplKey<'a>),
+ CxxVector(NamedImplKey<'a>),
+}
+
+#[derive(Copy, Clone)]
+pub struct NamedImplKey<'a> {
+ pub rust: &'a Ident,
+ pub lt_token: Option<Token![<]>,
+ pub gt_token: Option<Token![>]>,
}
impl Type {
pub(crate) fn impl_key(&self) -> Option<ImplKey> {
if let Type::RustBox(ty) = self {
if let Type::Ident(ident) = &ty.inner {
- return Some(ImplKey::RustBox(&ident.rust));
+ return Some(ImplKey::RustBox(NamedImplKey::from(ident)));
}
} else if let Type::RustVec(ty) = self {
if let Type::Ident(ident) = &ty.inner {
- return Some(ImplKey::RustVec(&ident.rust));
+ return Some(ImplKey::RustVec(NamedImplKey::from(ident)));
}
} else if let Type::UniquePtr(ty) = self {
if let Type::Ident(ident) = &ty.inner {
- return Some(ImplKey::UniquePtr(&ident.rust));
+ return Some(ImplKey::UniquePtr(NamedImplKey::from(ident)));
}
} else if let Type::SharedPtr(ty) = self {
if let Type::Ident(ident) = &ty.inner {
- return Some(ImplKey::SharedPtr(&ident.rust));
+ return Some(ImplKey::SharedPtr(NamedImplKey::from(ident)));
}
} else if let Type::WeakPtr(ty) = self {
if let Type::Ident(ident) = &ty.inner {
- return Some(ImplKey::WeakPtr(&ident.rust));
+ return Some(ImplKey::WeakPtr(NamedImplKey::from(ident)));
}
} else if let Type::CxxVector(ty) = self {
if let Type::Ident(ident) = &ty.inner {
- return Some(ImplKey::CxxVector(&ident.rust));
+ return Some(ImplKey::CxxVector(NamedImplKey::from(ident)));
}
}
None
}
}
+
+impl<'a> PartialEq for NamedImplKey<'a> {
+ fn eq(&self, other: &Self) -> bool {
+ PartialEq::eq(self.rust, other.rust)
+ }
+}
+
+impl<'a> Eq for NamedImplKey<'a> {}
+
+impl<'a> Hash for NamedImplKey<'a> {
+ fn hash<H: Hasher>(&self, hasher: &mut H) {
+ self.rust.hash(hasher);
+ }
+}
+
+impl<'a> From<&'a NamedType> for NamedImplKey<'a> {
+ fn from(ty: &'a NamedType) -> Self {
+ NamedImplKey {
+ rust: &ty.rust,
+ lt_token: ty.generics.lt_token,
+ gt_token: ty.generics.gt_token,
+ }
+ }
+}
diff --git a/syntax/types.rs b/syntax/types.rs
index 196a1db..af7916d 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -171,7 +171,7 @@
| ImplKey::SharedPtr(ident)
| ImplKey::WeakPtr(ident)
| ImplKey::CxxVector(ident) => {
- Atom::from(ident).is_none() && !aliases.contains_key(ident)
+ Atom::from(ident.rust).is_none() && !aliases.contains_key(ident.rust)
}
};
if implicit_impl && !impls.contains_key(&impl_key) {