if path != "std::ops::Deref" && path != "core::ops::Deref" &&
path != "std::ops::DerefMut" && path != "core::ops::DerefMut" {
self.typed_generics.insert(&t.ident, path);
+ } else {
+ let last_seg_args = &tr.path.segments.last().unwrap().arguments;
+ if let syn::PathArguments::AngleBracketed(args) = last_seg_args {
+ assert_eq!(args.args.len(), 1);
+ if let syn::GenericArgument::Binding(binding) = &args.args[0] {
+ assert_eq!(format!("{}", binding.ident), "Target");
+ if let syn::Type::Path(p) = &binding.ty {
+ // Note that we are assuming the order of type
+ // declarations here, but that should be easy
+ // to handle.
+ let real_path = self.maybe_resolve_path(&p.path).unwrap();
+ self.typed_generics.insert(&t.ident, real_path.clone());
+ } else { unimplemented!(); }
+ } else { unimplemented!(); }
+ } else { unimplemented!(); }
}
} else { unimplemented!(); }
for bound in bounds_iter {
Some(first_seg_str + &remaining)
} else if first_seg_str == "crate" {
Some(self.crate_name.to_owned() + &remaining)
+ } else if self.library.modules.get(&format!("{}::{}", self.module_path, first_seg.ident)).is_some() {
+ Some(format!("{}::{}{}", self.module_path, first_seg.ident, remaining))
} else { None }
}
}
pub fn maybe_resolve_path(&self, p: &syn::Path, generics: Option<&GenericTypes>) -> Option<String> {
self.maybe_resolve_imported_path(p, generics).map(|mut path| {
+ if path == "core::ops::Deref" || path == "core::ops::DerefMut" {
+ let last_seg = p.segments.last().unwrap();
+ if let syn::PathArguments::AngleBracketed(args) = &last_seg.arguments {
+ assert_eq!(args.args.len(), 1);
+ if let syn::GenericArgument::Binding(binding) = &args.args[0] {
+ if let syn::Type::Path(p) = &binding.ty {
+ if let Some(inner_ty) = self.maybe_resolve_path(&p.path, generics) {
+ let mut module_riter = inner_ty.rsplitn(2, "::");
+ let ty_ident = module_riter.next().unwrap();
+ let module_name = module_riter.next().unwrap();
+ let module = self.library.modules.get(module_name).unwrap();
+ for item in module.items.iter() {
+ match item {
+ syn::Item::Trait(t) => {
+ if t.ident == ty_ident {
+ path = inner_ty;
+ break;
+ }
+ },
+ _ => {}
+ }
+ }
+ }
+ } else { unimplemented!(); }
+ } else { unimplemented!(); }
+ }
+ }
loop {
// Now that we've resolved the path to the path as-imported, check whether the path
// is actually a pub(.*) use statement and map it to the real path.
generics, &subtype, is_ref, is_mut, ptr_for_ref, true);
}
} else {
- let id = subtype.rsplitn(2, ':').next().unwrap(); // Get the "Base" name of the resolved type
+ let mut resolved = Vec::new();
+ let id =
+ if self.write_c_path_intern(&mut resolved, &$p_arg.path, generics, false, false, false, false, false) {
+ let inner = std::str::from_utf8(&resolved).unwrap();
+ inner.rsplitn(2, "::").next().unwrap()
+ } else {
+ subtype.rsplitn(2, "::").next().unwrap()
+ };
write!(w, "{}", id).unwrap();
write!(mangled_type, "{}", id).unwrap();
if let Some(w2) = $extra_write as Option<&mut Vec<u8>> {
} else { return false; }
} else if let syn::Type::Array(_) = elem {
let mut resolved = Vec::new();
- if !self.write_c_type_intern(&mut resolved, &elem, generics, false, false, true, false, true) { return false; }
+ if !self.write_c_type_intern(&mut resolved, &elem, generics, false, false, false, false, false) { return false; }
let array_inner = String::from_utf8(resolved).unwrap();
- let arr_name = array_inner.split("::").last().unwrap();
+ let arr_name = array_inner.rsplitn(2, "::").next().unwrap();
write!(w, "{}", arr_name).unwrap();
write!(mangled_type, "{}", arr_name).unwrap();
} else { return false; }
// If this is a no-export'd crate and there's only one implementation in the
// whole crate, just treat it as a reference to whatever the implementor is.
if with_ref_lifetime {
- write!(w, "&'static crate::{}", trait_impls[0]).unwrap();
+ // Hope we're being printed in function generics and let rustc derive the
+ // type.
+ write!(w, "_").unwrap();
} else {
write!(w, "&crate::{}", trait_impls[0]).unwrap();
}