diff --git a/gen/src/write.rs b/gen/src/write.rs index 5e2473a14..73a4b8c80 100644 --- a/gen/src/write.rs +++ b/gen/src/write.rs @@ -657,7 +657,7 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) { write!( out, "{} &self", - out.types.resolve(&receiver.ty).to_fully_qualified(), + out.types.resolve(&receiver.ty).name.to_fully_qualified(), ); } for (i, arg) in efn.args.iter().enumerate() { @@ -687,7 +687,7 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) { Some(receiver) => write!( out, "({}::*{}$)(", - out.types.resolve(&receiver.ty).to_fully_qualified(), + out.types.resolve(&receiver.ty).name.to_fully_qualified(), efn.name.rust, ), } @@ -709,7 +709,7 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) { Some(receiver) => write!( out, "&{}::{}", - out.types.resolve(&receiver.ty).to_fully_qualified(), + out.types.resolve(&receiver.ty).name.to_fully_qualified(), efn.name.cxx, ), } @@ -868,7 +868,7 @@ fn write_rust_function_decl_impl( write!( out, "{} &self", - out.types.resolve(&receiver.ty).to_fully_qualified(), + out.types.resolve(&receiver.ty).name.to_fully_qualified(), ); needs_comma = true; } @@ -903,7 +903,11 @@ fn write_rust_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) { } let local_name = match &efn.sig.receiver { None => efn.name.cxx.to_string(), - Some(receiver) => format!("{}::{}", out.types.resolve(&receiver.ty).cxx, efn.name.cxx), + Some(receiver) => format!( + "{}::{}", + out.types.resolve(&receiver.ty).name.cxx, + efn.name.cxx, + ), }; let invoke = mangle::extern_fn(efn, out.types); let indirect_call = false; @@ -1160,7 +1164,11 @@ fn write_type(out: &mut OutFile, ty: &Type) { match ty { Type::Ident(ident) => match Atom::from(&ident.rust) { Some(atom) => write_atom(out, atom), - None => write!(out, "{}", out.types.resolve(ident).to_fully_qualified()), + None => write!( + out, + "{}", + out.types.resolve(ident).name.to_fully_qualified(), + ), }, Type::RustBox(ty) => { write!(out, "::rust::Box<"); @@ -1290,7 +1298,7 @@ trait ToTypename { impl ToTypename for Ident { fn to_typename(&self, types: &Types) -> String { - types.resolve(self).to_fully_qualified() + types.resolve(self).name.to_fully_qualified() } } @@ -1311,7 +1319,7 @@ trait ToMangled { impl ToMangled for Ident { fn to_mangled(&self, types: &Types) -> Symbol { - types.resolve(self).to_symbol() + types.resolve(self).name.to_symbol() } } @@ -1360,8 +1368,8 @@ fn write_generic_instantiations(out: &mut OutFile) { fn write_rust_box_extern(out: &mut OutFile, ident: &Ident) { let resolve = out.types.resolve(ident); - let inner = resolve.to_fully_qualified(); - let instance = resolve.to_symbol(); + let inner = resolve.name.to_fully_qualified(); + let instance = resolve.name.to_symbol(); writeln!( out, @@ -1425,8 +1433,8 @@ fn write_rust_vec_extern(out: &mut OutFile, element: &Ident) { fn write_rust_box_impl(out: &mut OutFile, ident: &Ident) { let resolve = out.types.resolve(ident); - let inner = resolve.to_fully_qualified(); - let instance = resolve.to_symbol(); + let inner = resolve.name.to_fully_qualified(); + let instance = resolve.name.to_symbol(); writeln!(out, "template <>"); begin_function_definition(out); @@ -1567,7 +1575,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) { if conditional_delete { out.builtin.is_complete = true; let definition = match ty { - UniquePtr::Ident(ty) => &out.types.resolve(ty).cxx, + UniquePtr::Ident(ty) => &out.types.resolve(ty).name.cxx, UniquePtr::CxxVector(_) => unreachable!(), }; writeln!( @@ -1650,8 +1658,8 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) { fn write_shared_ptr(out: &mut OutFile, ident: &Ident) { let resolve = out.types.resolve(ident); - let inner = resolve.to_fully_qualified(); - let instance = resolve.to_symbol(); + let inner = resolve.name.to_fully_qualified(); + let instance = resolve.name.to_symbol(); out.include.new = true; out.include.utility = true; @@ -1722,8 +1730,8 @@ fn write_shared_ptr(out: &mut OutFile, ident: &Ident) { fn write_weak_ptr(out: &mut OutFile, ident: &Ident) { let resolve = out.types.resolve(ident); - let inner = resolve.to_fully_qualified(); - let instance = resolve.to_symbol(); + let inner = resolve.name.to_fully_qualified(); + let instance = resolve.name.to_symbol(); out.include.new = true; out.include.utility = true; diff --git a/macro/src/expand.rs b/macro/src/expand.rs index d67361ad7..8149d5d9e 100644 --- a/macro/src/expand.rs +++ b/macro/src/expand.rs @@ -1038,7 +1038,7 @@ fn type_id(name: &Pair) -> TokenStream { fn expand_rust_box(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { let resolve = types.resolve(ident); - let link_prefix = format!("cxxbridge1$box${}$", resolve.to_symbol()); + let link_prefix = format!("cxxbridge1$box${}$", resolve.name.to_symbol()); let link_alloc = format!("{}alloc", link_prefix); let link_dealloc = format!("{}dealloc", link_prefix); let link_drop = format!("{}drop", link_prefix); @@ -1076,7 +1076,7 @@ fn expand_rust_box(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) - fn expand_rust_vec(elem: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { let resolve = types.resolve(elem); - let link_prefix = format!("cxxbridge1$rust_vec${}$", resolve.to_symbol()); + let link_prefix = format!("cxxbridge1$rust_vec${}$", resolve.name.to_symbol()); let link_new = format!("{}new", link_prefix); let link_drop = format!("{}drop", link_prefix); let link_len = format!("{}len", link_prefix); @@ -1143,7 +1143,7 @@ fn expand_rust_vec(elem: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> fn expand_unique_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { let name = ident.to_string(); let resolve = types.resolve(ident); - let prefix = format!("cxxbridge1$unique_ptr${}$", resolve.to_symbol()); + let prefix = format!("cxxbridge1$unique_ptr${}$", resolve.name.to_symbol()); let link_null = format!("{}null", prefix); let link_uninit = format!("{}uninit", prefix); let link_raw = format!("{}raw", prefix); @@ -1225,7 +1225,7 @@ fn expand_unique_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) fn expand_shared_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { let name = ident.to_string(); let resolve = types.resolve(ident); - let prefix = format!("cxxbridge1$shared_ptr${}$", resolve.to_symbol()); + let prefix = format!("cxxbridge1$shared_ptr${}$", resolve.name.to_symbol()); let link_null = format!("{}null", prefix); let link_uninit = format!("{}uninit", prefix); let link_clone = format!("{}clone", prefix); @@ -1293,7 +1293,7 @@ fn expand_shared_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) fn expand_weak_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { let name = ident.to_string(); let resolve = types.resolve(ident); - let prefix = format!("cxxbridge1$weak_ptr${}$", resolve.to_symbol()); + let prefix = format!("cxxbridge1$weak_ptr${}$", resolve.name.to_symbol()); let link_null = format!("{}null", prefix); let link_clone = format!("{}clone", prefix); let link_downgrade = format!("{}downgrade", prefix); @@ -1350,10 +1350,13 @@ fn expand_weak_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) - fn expand_cxx_vector(elem: &Ident, explicit_impl: Option<&Impl>, types: &Types) -> TokenStream { let name = elem.to_string(); let resolve = types.resolve(elem); - let prefix = format!("cxxbridge1$std$vector${}$", resolve.to_symbol()); + let prefix = format!("cxxbridge1$std$vector${}$", resolve.name.to_symbol()); let link_size = format!("{}size", prefix); let link_get_unchecked = format!("{}get_unchecked", prefix); - let unique_ptr_prefix = format!("cxxbridge1$unique_ptr$std$vector${}$", resolve.to_symbol()); + let unique_ptr_prefix = format!( + "cxxbridge1$unique_ptr$std$vector${}$", + resolve.name.to_symbol(), + ); let link_unique_ptr_null = format!("{}null", unique_ptr_prefix); let link_unique_ptr_raw = format!("{}raw", unique_ptr_prefix); let link_unique_ptr_get = format!("{}get", unique_ptr_prefix); diff --git a/syntax/mangle.rs b/syntax/mangle.rs index 71a60be6c..901830aec 100644 --- a/syntax/mangle.rs +++ b/syntax/mangle.rs @@ -16,7 +16,7 @@ pub fn extern_fn(efn: &ExternFn, types: &Types) -> Symbol { join!( efn.name.namespace, CXXBRIDGE, - receiver_ident.cxx, + receiver_ident.name.cxx, efn.name.rust, ) } diff --git a/syntax/resolve.rs b/syntax/resolve.rs index 5bb15357a..08fcf1650 100644 --- a/syntax/resolve.rs +++ b/syntax/resolve.rs @@ -1,9 +1,16 @@ -use crate::syntax::{NamedType, Pair, Types}; +use crate::syntax::{Lifetimes, NamedType, Pair, Types}; use proc_macro2::Ident; +#[derive(Copy, Clone)] +pub struct Resolution<'a> { + pub name: &'a Pair, + pub generics: &'a Lifetimes, +} + impl<'a> Types<'a> { - pub fn resolve(&self, ident: &impl UnresolvedName) -> &Pair { - self.resolutions + pub fn resolve(&self, ident: &impl UnresolvedName) -> Resolution<'a> { + *self + .resolutions .get(ident.ident()) .expect("Unable to resolve type") } diff --git a/syntax/types.rs b/syntax/types.rs index 0eb4293c7..7bf2baf0e 100644 --- a/syntax/types.rs +++ b/syntax/types.rs @@ -2,9 +2,12 @@ use crate::syntax::improper::ImproperCtype; use crate::syntax::instantiate::ImplKey; use crate::syntax::map::{OrderedMap, UnorderedMap}; use crate::syntax::report::Errors; +use crate::syntax::resolve::Resolution; use crate::syntax::set::{OrderedSet, UnorderedSet}; use crate::syntax::trivial::{self, TrivialReason}; -use crate::syntax::{toposort, Api, Atom, Enum, ExternType, Impl, Pair, Struct, Type, TypeAlias}; +use crate::syntax::{ + toposort, Api, Atom, Enum, ExternType, Impl, Lifetimes, Pair, Struct, Type, TypeAlias, +}; use proc_macro2::Ident; use quote::ToTokens; @@ -18,7 +21,7 @@ pub struct Types<'a> { pub untrusted: UnorderedMap<&'a Ident, &'a ExternType>, pub required_trivial: UnorderedMap<&'a Ident, Vec>>, pub impls: OrderedMap, Option<&'a Impl>>, - pub resolutions: UnorderedMap<&'a Ident, &'a Pair>, + pub resolutions: UnorderedMap<&'a Ident, Resolution<'a>>, pub struct_improper_ctypes: UnorderedSet<&'a Ident>, pub toposorted_structs: Vec<&'a Struct>, } @@ -61,8 +64,8 @@ impl<'a> Types<'a> { } } - let mut add_resolution = |pair: &'a Pair| { - resolutions.insert(&pair.rust, pair); + let mut add_resolution = |name: &'a Pair, generics: &'a Lifetimes| { + resolutions.insert(&name.rust, Resolution { name, generics }); }; let mut type_names = UnorderedSet::new(); @@ -92,7 +95,7 @@ impl<'a> Types<'a> { for field in &strct.fields { visit(&mut all, &field.ty); } - add_resolution(&strct.name); + add_resolution(&strct.name, &strct.generics); } Api::Enum(enm) => { all.insert(&enm.repr_type); @@ -108,7 +111,7 @@ impl<'a> Types<'a> { duplicate_name(cx, enm, ident); } enums.insert(ident, enm); - add_resolution(&enm.name); + add_resolution(&enm.name, &enm.generics); } Api::CxxType(ety) => { let ident = &ety.name.rust; @@ -125,7 +128,7 @@ impl<'a> Types<'a> { if !ety.trusted { untrusted.insert(ident, ety); } - add_resolution(&ety.name); + add_resolution(&ety.name, &ety.generics); } Api::RustType(ety) => { let ident = &ety.name.rust; @@ -133,7 +136,7 @@ impl<'a> Types<'a> { duplicate_name(cx, ety, ident); } rust.insert(ident); - add_resolution(&ety.name); + add_resolution(&ety.name, &ety.generics); } Api::CxxFunction(efn) | Api::RustFunction(efn) => { // Note: duplication of the C++ name is fine because C++ has @@ -155,7 +158,7 @@ impl<'a> Types<'a> { } cxx.insert(ident); aliases.insert(ident, alias); - add_resolution(&alias.name); + add_resolution(&alias.name, &alias.generics); } Api::Impl(imp) => { visit(&mut all, &imp.ty);