Generate all explicit and implicit impls based on one map
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 96592b3..6679076 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -3,13 +3,14 @@
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::map::UnorderedMap as Map;
use crate::syntax::set::UnorderedSet;
use crate::syntax::symbol::Symbol;
use crate::syntax::trivial::{self, TrivialReason};
use crate::syntax::{
- derive, mangle, Api, Enum, ExternFn, ExternType, NamedType, Pair, Signature, Struct, Trait,
- Type, TypeAlias, Types, Var,
+ derive, mangle, Api, Enum, ExternFn, ExternType, Pair, Signature, Struct, Trait, Type,
+ TypeAlias, Types, Var,
};
use proc_macro2::Ident;
@@ -1284,15 +1285,15 @@
#[derive(Copy, Clone)]
enum UniquePtr<'a> {
- Ident(&'a NamedType),
- CxxVector(&'a NamedType),
+ Ident(&'a Ident),
+ CxxVector(&'a Ident),
}
trait ToTypename {
fn to_typename(&self, types: &Types) -> String;
}
-impl ToTypename for NamedType {
+impl ToTypename for Ident {
fn to_typename(&self, types: &Types) -> String {
types.resolve(self).to_fully_qualified()
}
@@ -1313,7 +1314,7 @@
fn to_mangled(&self, types: &Types) -> Symbol;
}
-impl ToMangled for NamedType {
+impl ToMangled for Ident {
fn to_mangled(&self, types: &Types) -> Symbol {
types.resolve(self).to_symbol()
}
@@ -1336,109 +1337,36 @@
out.next_section();
out.set_namespace(Default::default());
out.begin_block(Block::ExternC);
- for ty in out.types {
- let impl_key = match ty.impl_key() {
- Some(impl_key) => impl_key,
- None => continue,
- };
- if let Type::RustBox(ptr) = ty {
- if let Type::Ident(inner) = &ptr.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_rust_box_extern(out, &out.types.resolve(&inner));
- }
- }
- } else if let Type::RustVec(vec) = ty {
- if let Type::Ident(inner) = &vec.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_rust_vec_extern(out, inner);
- }
- }
- } else if let Type::UniquePtr(ptr) = ty {
- if let Type::Ident(inner) = &ptr.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_unique_ptr(out, inner);
- }
- }
- } else if let Type::SharedPtr(ptr) = ty {
- if let Type::Ident(inner) = &ptr.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_shared_ptr(out, inner);
- }
- }
- } else if let Type::WeakPtr(ptr) = ty {
- if let Type::Ident(inner) = &ptr.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_weak_ptr(out, inner);
- }
- }
- } else if let Type::CxxVector(vector) = ty {
- if let Type::Ident(inner) = &vector.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_cxx_vector(out, inner);
- }
- }
+ for impl_key in out.types.impls.keys() {
+ out.next_section();
+ 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),
+ ImplKey::SharedPtr(ident) => write_shared_ptr(out, ident),
+ ImplKey::WeakPtr(ident) => write_weak_ptr(out, ident),
+ ImplKey::CxxVector(ident) => write_cxx_vector(out, ident),
}
}
out.end_block(Block::ExternC);
out.begin_block(Block::Namespace("rust"));
out.begin_block(Block::InlineNamespace("cxxbridge1"));
- for ty in out.types {
- let impl_key = match ty.impl_key() {
- Some(impl_key) => impl_key,
- None => continue,
- };
- if let Type::RustBox(ptr) = ty {
- if let Type::Ident(inner) = &ptr.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- write_rust_box_impl(out, &out.types.resolve(&inner));
- }
- }
- } else if let Type::RustVec(vec) = ty {
- if let Type::Ident(inner) = &vec.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- write_rust_vec_impl(out, inner);
- }
- }
+ for impl_key in out.types.impls.keys() {
+ match impl_key {
+ ImplKey::RustBox(ident) => write_rust_box_impl(out, ident),
+ ImplKey::RustVec(ident) => write_rust_vec_impl(out, ident),
+ _ => {}
}
}
out.end_block(Block::InlineNamespace("cxxbridge1"));
out.end_block(Block::Namespace("rust"));
}
-fn write_rust_box_extern(out: &mut OutFile, ident: &Pair) {
- let inner = ident.to_fully_qualified();
- let instance = ident.to_symbol();
+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();
writeln!(
out,
@@ -1457,7 +1385,7 @@
);
}
-fn write_rust_vec_extern(out: &mut OutFile, element: &NamedType) {
+fn write_rust_vec_extern(out: &mut OutFile, element: &Ident) {
let inner = element.to_typename(out.types);
let instance = element.to_mangled(out.types);
@@ -1500,9 +1428,10 @@
);
}
-fn write_rust_box_impl(out: &mut OutFile, ident: &Pair) {
- let inner = ident.to_fully_qualified();
- let instance = ident.to_symbol();
+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();
writeln!(out, "template <>");
begin_function_definition(out);
@@ -1531,7 +1460,7 @@
writeln!(out, "}}");
}
-fn write_rust_vec_impl(out: &mut OutFile, element: &NamedType) {
+fn write_rust_vec_impl(out: &mut OutFile, element: &Ident) {
let inner = element.to_typename(out.types);
let instance = element.to_mangled(out.types);
@@ -1608,7 +1537,7 @@
writeln!(out, "}}");
}
-fn write_unique_ptr(out: &mut OutFile, ident: &NamedType) {
+fn write_unique_ptr(out: &mut OutFile, ident: &Ident) {
let ty = UniquePtr::Ident(ident);
write_unique_ptr_common(out, ty);
}
@@ -1626,17 +1555,16 @@
// bindings for a "new" method anyway. But the Rust code can't be called
// for Opaque types because the 'new' method is not implemented.
UniquePtr::Ident(ident) => {
- out.types.structs.contains_key(&ident.rust)
- || out.types.enums.contains_key(&ident.rust)
- || out.types.aliases.contains_key(&ident.rust)
+ out.types.structs.contains_key(ident)
+ || out.types.enums.contains_key(ident)
+ || out.types.aliases.contains_key(ident)
}
UniquePtr::CxxVector(_) => false,
};
let conditional_delete = match ty {
UniquePtr::Ident(ident) => {
- !out.types.structs.contains_key(&ident.rust)
- && !out.types.enums.contains_key(&ident.rust)
+ !out.types.structs.contains_key(ident) && !out.types.enums.contains_key(ident)
}
UniquePtr::CxxVector(_) => false,
};
@@ -1725,7 +1653,7 @@
writeln!(out, "}}");
}
-fn write_shared_ptr(out: &mut OutFile, ident: &NamedType) {
+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();
@@ -1737,9 +1665,9 @@
// know at code generation time, so we generate both C++ and Rust side
// bindings for a "new" method anyway. But the Rust code can't be called for
// Opaque types because the 'new' method is not implemented.
- let can_construct_from_value = out.types.structs.contains_key(&ident.rust)
- || out.types.enums.contains_key(&ident.rust)
- || out.types.aliases.contains_key(&ident.rust);
+ let can_construct_from_value = out.types.structs.contains_key(ident)
+ || out.types.enums.contains_key(ident)
+ || out.types.aliases.contains_key(ident);
writeln!(
out,
@@ -1797,7 +1725,7 @@
writeln!(out, "}}");
}
-fn write_weak_ptr(out: &mut OutFile, ident: &NamedType) {
+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();
@@ -1856,7 +1784,7 @@
writeln!(out, "}}");
}
-fn write_cxx_vector(out: &mut OutFile, element: &NamedType) {
+fn write_cxx_vector(out: &mut OutFile, element: &Ident) {
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 90b835a..40ed5e2 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -1,12 +1,13 @@
use crate::derive;
-use crate::syntax::atom::Atom::{self, *};
+use crate::syntax::atom::Atom::*;
use crate::syntax::attrs::{self, OtherAttrs};
use crate::syntax::file::Module;
+use crate::syntax::instantiate::ImplKey;
use crate::syntax::report::Errors;
use crate::syntax::symbol::Symbol;
use crate::syntax::{
- self, check, mangle, Api, Doc, Enum, ExternFn, ExternType, Impl, NamedType, Pair, Signature,
- Struct, Trait, Type, TypeAlias, Types,
+ self, check, mangle, Api, Doc, Enum, ExternFn, ExternType, Impl, Pair, Signature, Struct,
+ Trait, Type, TypeAlias, Types,
};
use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote, quote_spanned, ToTokens};
@@ -79,62 +80,25 @@
}
}
- for ty in types {
- let impl_key = match ty.impl_key() {
- Some(impl_key) => impl_key,
- None => continue,
- };
- let explicit_impl = types.explicit_impls.get(&impl_key).copied();
- if let Type::RustBox(ty) = ty {
- if let Type::Ident(ident) = &ty.inner {
- if Atom::from(&ident.rust).is_none()
- && (explicit_impl.is_some() || !types.aliases.contains_key(&ident.rust))
- {
- hidden.extend(expand_rust_box(ident, types, explicit_impl));
- }
+ for (impl_key, &explicit_impl) in &types.impls {
+ match impl_key {
+ ImplKey::RustBox(ident) => {
+ hidden.extend(expand_rust_box(ident, types, explicit_impl));
}
- } else if let Type::RustVec(ty) = ty {
- if let Type::Ident(ident) = &ty.inner {
- if Atom::from(&ident.rust).is_none()
- && (explicit_impl.is_some() || !types.aliases.contains_key(&ident.rust))
- {
- hidden.extend(expand_rust_vec(ident, types, explicit_impl));
- }
+ ImplKey::RustVec(ident) => {
+ hidden.extend(expand_rust_vec(ident, types, explicit_impl));
}
- } else if let Type::UniquePtr(ptr) = ty {
- if let Type::Ident(ident) = &ptr.inner {
- if Atom::from(&ident.rust).is_none()
- && (explicit_impl.is_some() || !types.aliases.contains_key(&ident.rust))
- {
- expanded.extend(expand_unique_ptr(ident, types, explicit_impl));
- }
+ ImplKey::UniquePtr(ident) => {
+ expanded.extend(expand_unique_ptr(ident, types, explicit_impl));
}
- } else if let Type::SharedPtr(ptr) = ty {
- if let Type::Ident(ident) = &ptr.inner {
- if Atom::from(&ident.rust).is_none()
- && (explicit_impl.is_some() || !types.aliases.contains_key(&ident.rust))
- {
- expanded.extend(expand_shared_ptr(ident, types, explicit_impl));
- }
+ ImplKey::SharedPtr(ident) => {
+ expanded.extend(expand_shared_ptr(ident, types, explicit_impl));
}
- } else if let Type::WeakPtr(ptr) = ty {
- if let Type::Ident(ident) = &ptr.inner {
- if Atom::from(&ident.rust).is_none()
- && (explicit_impl.is_some() || !types.aliases.contains_key(&ident.rust))
- {
- expanded.extend(expand_weak_ptr(ident, types, explicit_impl));
- }
+ ImplKey::WeakPtr(ident) => {
+ expanded.extend(expand_weak_ptr(ident, types, explicit_impl));
}
- } else if let Type::CxxVector(ptr) = ty {
- if let Type::Ident(ident) = &ptr.inner {
- if Atom::from(&ident.rust).is_none()
- && (explicit_impl.is_some() || !types.aliases.contains_key(&ident.rust))
- {
- // Generate impl for CxxVector<T> if T is a struct or opaque
- // C++ type. Impl for primitives is already provided by cxx
- // crate.
- expanded.extend(expand_cxx_vector(ident, explicit_impl, types));
- }
+ ImplKey::CxxVector(ident) => {
+ expanded.extend(expand_cxx_vector(ident, explicit_impl, types));
}
}
}
@@ -1071,14 +1035,14 @@
}
}
-fn expand_rust_box(ident: &NamedType, types: &Types, explicit_impl: Option<&Impl>) -> 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_alloc = format!("{}alloc", link_prefix);
let link_dealloc = format!("{}dealloc", link_prefix);
let link_drop = format!("{}drop", link_prefix);
- let local_prefix = format_ident!("{}__box_", &ident.rust);
+ let local_prefix = format_ident!("{}__box_", ident);
let local_alloc = format_ident!("{}alloc", local_prefix);
let local_dealloc = format_ident!("{}dealloc", local_prefix);
let local_drop = format_ident!("{}drop", local_prefix);
@@ -1109,7 +1073,7 @@
}
}
-fn expand_rust_vec(elem: &NamedType, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream {
+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_new = format!("{}new", link_prefix);
@@ -1120,7 +1084,7 @@
let link_reserve_total = format!("{}reserve_total", link_prefix);
let link_set_len = format!("{}set_len", link_prefix);
- let local_prefix = format_ident!("{}__vec_", elem.rust);
+ let local_prefix = format_ident!("{}__vec_", elem);
let local_new = format_ident!("{}new", local_prefix);
let local_drop = format_ident!("{}drop", local_prefix);
let local_len = format_ident!("{}len", local_prefix);
@@ -1175,12 +1139,8 @@
}
}
-fn expand_unique_ptr(
- ident: &NamedType,
- types: &Types,
- explicit_impl: Option<&Impl>,
-) -> TokenStream {
- let name = ident.rust.to_string();
+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 link_null = format!("{}null", prefix);
@@ -1190,9 +1150,9 @@
let link_release = format!("{}release", prefix);
let link_drop = format!("{}drop", prefix);
- let can_construct_from_value = types.structs.contains_key(&ident.rust)
- || types.enums.contains_key(&ident.rust)
- || types.aliases.contains_key(&ident.rust);
+ let can_construct_from_value = types.structs.contains_key(ident)
+ || types.enums.contains_key(ident)
+ || types.aliases.contains_key(ident);
let new_method = if can_construct_from_value {
Some(quote! {
fn __new(value: Self) -> *mut ::std::ffi::c_void {
@@ -1261,12 +1221,8 @@
}
}
-fn expand_shared_ptr(
- ident: &NamedType,
- types: &Types,
- explicit_impl: Option<&Impl>,
-) -> TokenStream {
- let name = ident.rust.to_string();
+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 link_null = format!("{}null", prefix);
@@ -1275,9 +1231,9 @@
let link_get = format!("{}get", prefix);
let link_drop = format!("{}drop", prefix);
- let can_construct_from_value = types.structs.contains_key(&ident.rust)
- || types.enums.contains_key(&ident.rust)
- || types.aliases.contains_key(&ident.rust);
+ let can_construct_from_value = types.structs.contains_key(ident)
+ || types.enums.contains_key(ident)
+ || types.aliases.contains_key(ident);
let new_method = if can_construct_from_value {
Some(quote! {
unsafe fn __new(value: Self, new: *mut ::std::ffi::c_void) {
@@ -1333,8 +1289,8 @@
}
}
-fn expand_weak_ptr(ident: &NamedType, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream {
- let name = ident.rust.to_string();
+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 link_null = format!("{}null", prefix);
@@ -1390,8 +1346,8 @@
}
}
-fn expand_cxx_vector(elem: &NamedType, explicit_impl: Option<&Impl>, types: &Types) -> TokenStream {
- let name = elem.rust.to_string();
+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 link_size = format!("{}size", prefix);
diff --git a/syntax/map.rs b/syntax/map.rs
index f1ea5fc..4873409 100644
--- a/syntax/map.rs
+++ b/syntax/map.rs
@@ -29,6 +29,10 @@
pub fn iter(&self) -> Iter<K, V> {
Iter(self.vec.iter())
}
+
+ pub fn keys(&self) -> impl Iterator<Item = &K> {
+ self.vec.iter().map(|(k, _v)| k)
+ }
}
impl<K, V> OrderedMap<K, V>
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 3a77b82..4298995 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -20,6 +20,7 @@
mod pod;
pub mod qualified;
pub mod report;
+mod resolve;
pub mod set;
pub mod symbol;
mod tokens;
diff --git a/syntax/resolve.rs b/syntax/resolve.rs
new file mode 100644
index 0000000..5bb1535
--- /dev/null
+++ b/syntax/resolve.rs
@@ -0,0 +1,26 @@
+use crate::syntax::{NamedType, Pair, Types};
+use proc_macro2::Ident;
+
+impl<'a> Types<'a> {
+ pub fn resolve(&self, ident: &impl UnresolvedName) -> &Pair {
+ self.resolutions
+ .get(ident.ident())
+ .expect("Unable to resolve type")
+ }
+}
+
+pub trait UnresolvedName {
+ fn ident(&self) -> &Ident;
+}
+
+impl UnresolvedName for Ident {
+ fn ident(&self) -> &Ident {
+ self
+ }
+}
+
+impl UnresolvedName for NamedType {
+ fn ident(&self) -> &Ident {
+ &self.rust
+ }
+}
diff --git a/syntax/types.rs b/syntax/types.rs
index 54cd8f0..0eb4293 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -1,17 +1,15 @@
use crate::syntax::improper::ImproperCtype;
use crate::syntax::instantiate::ImplKey;
-use crate::syntax::map::UnorderedMap;
+use crate::syntax::map::{OrderedMap, UnorderedMap};
use crate::syntax::report::Errors;
-use crate::syntax::set::{OrderedSet as Set, UnorderedSet};
+use crate::syntax::set::{OrderedSet, UnorderedSet};
use crate::syntax::trivial::{self, TrivialReason};
-use crate::syntax::{
- toposort, Api, Enum, ExternType, Impl, NamedType, Pair, Struct, Type, TypeAlias,
-};
+use crate::syntax::{toposort, Api, Atom, Enum, ExternType, Impl, Pair, Struct, Type, TypeAlias};
use proc_macro2::Ident;
use quote::ToTokens;
pub struct Types<'a> {
- pub all: Set<&'a Type>,
+ pub all: OrderedSet<&'a Type>,
pub structs: UnorderedMap<&'a Ident, &'a Struct>,
pub enums: UnorderedMap<&'a Ident, &'a Enum>,
pub cxx: UnorderedSet<&'a Ident>,
@@ -19,7 +17,7 @@
pub aliases: UnorderedMap<&'a Ident, &'a TypeAlias>,
pub untrusted: UnorderedMap<&'a Ident, &'a ExternType>,
pub required_trivial: UnorderedMap<&'a Ident, Vec<TrivialReason<'a>>>,
- pub explicit_impls: UnorderedMap<ImplKey<'a>, &'a Impl>,
+ pub impls: OrderedMap<ImplKey<'a>, Option<&'a Impl>>,
pub resolutions: UnorderedMap<&'a Ident, &'a Pair>,
pub struct_improper_ctypes: UnorderedSet<&'a Ident>,
pub toposorted_structs: Vec<&'a Struct>,
@@ -27,19 +25,19 @@
impl<'a> Types<'a> {
pub fn collect(cx: &mut Errors, apis: &'a [Api]) -> Self {
- let mut all = Set::new();
+ let mut all = OrderedSet::new();
let mut structs = UnorderedMap::new();
let mut enums = UnorderedMap::new();
let mut cxx = UnorderedSet::new();
let mut rust = UnorderedSet::new();
let mut aliases = UnorderedMap::new();
let mut untrusted = UnorderedMap::new();
- let mut explicit_impls = UnorderedMap::new();
+ let mut impls = OrderedMap::new();
let mut resolutions = UnorderedMap::new();
let struct_improper_ctypes = UnorderedSet::new();
let toposorted_structs = Vec::new();
- fn visit<'a>(all: &mut Set<&'a Type>, ty: &'a Type) {
+ fn visit<'a>(all: &mut OrderedSet<&'a Type>, ty: &'a Type) {
all.insert(ty);
match ty {
Type::Ident(_) | Type::Str(_) | Type::Void(_) => {}
@@ -162,12 +160,32 @@
Api::Impl(imp) => {
visit(&mut all, &imp.ty);
if let Some(key) = imp.ty.impl_key() {
- explicit_impls.insert(key, imp);
+ impls.insert(key, Some(imp));
}
}
}
}
+ for ty in &all {
+ let impl_key = match ty.impl_key() {
+ Some(impl_key) => impl_key,
+ None => continue,
+ };
+ let implicit_impl = match impl_key {
+ ImplKey::RustBox(ident)
+ | ImplKey::RustVec(ident)
+ | ImplKey::UniquePtr(ident)
+ | ImplKey::SharedPtr(ident)
+ | ImplKey::WeakPtr(ident)
+ | ImplKey::CxxVector(ident) => {
+ Atom::from(ident).is_none() && !aliases.contains_key(ident)
+ }
+ };
+ if implicit_impl && !impls.contains_key(&impl_key) {
+ impls.insert(impl_key, None);
+ }
+ }
+
// All these APIs may contain types passed by value. We need to ensure
// we check that this is permissible. We do this _after_ scanning all
// the APIs above, in case some function or struct references a type
@@ -184,7 +202,7 @@
aliases,
untrusted,
required_trivial,
- explicit_impls,
+ impls,
resolutions,
struct_improper_ctypes,
toposorted_structs,
@@ -239,12 +257,6 @@
ImproperCtype::Depends(ident) => self.struct_improper_ctypes.contains(ident),
}
}
-
- pub fn resolve(&self, ident: &NamedType) -> &Pair {
- self.resolutions
- .get(&ident.rust)
- .expect("Unable to resolve type")
- }
}
impl<'t, 'a> IntoIterator for &'t Types<'a> {