Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Record lifetimes associated with generic type instantiation #634

Merged
merged 1 commit into from
Jan 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 25 additions & 17 deletions gen/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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,
),
}
Expand All @@ -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,
),
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<");
Expand Down Expand Up @@ -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()
}
}

Expand All @@ -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()
}
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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!(
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
17 changes: 10 additions & 7 deletions macro/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion syntax/mangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
}
Expand Down
13 changes: 10 additions & 3 deletions syntax/resolve.rs
Original file line number Diff line number Diff line change
@@ -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")
}
Expand Down
21 changes: 12 additions & 9 deletions syntax/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -18,7 +21,7 @@ pub struct Types<'a> {
pub untrusted: UnorderedMap<&'a Ident, &'a ExternType>,
pub required_trivial: UnorderedMap<&'a Ident, Vec<TrivialReason<'a>>>,
pub impls: OrderedMap<ImplKey<'a>, 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>,
}
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -125,15 +128,15 @@ 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;
if !type_names.insert(ident) {
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
Expand All @@ -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);
Expand Down