Skip to content

Commit b20a8ec

Browse files
committed
Handle Deref<Self::Type> bounds as Self::Type's trait bound
1 parent 1afc4cc commit b20a8ec

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

c-bindings-gen/src/types.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,21 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
351351
if path != "std::ops::Deref" && path != "core::ops::Deref" &&
352352
path != "std::ops::DerefMut" && path != "core::ops::DerefMut" {
353353
self.typed_generics.insert(&t.ident, path);
354+
} else {
355+
let last_seg_args = &tr.path.segments.last().unwrap().arguments;
356+
if let syn::PathArguments::AngleBracketed(args) = last_seg_args {
357+
assert_eq!(args.args.len(), 1);
358+
if let syn::GenericArgument::Binding(binding) = &args.args[0] {
359+
assert_eq!(format!("{}", binding.ident), "Target");
360+
if let syn::Type::Path(p) = &binding.ty {
361+
// Note that we are assuming the order of type
362+
// declarations here, but that should be easy
363+
// to handle.
364+
let real_path = self.maybe_resolve_path(&p.path).unwrap();
365+
self.typed_generics.insert(&t.ident, real_path.clone());
366+
} else { unimplemented!(); }
367+
} else { unimplemented!(); }
368+
} else { unimplemented!(); }
354369
}
355370
} else { unimplemented!(); }
356371
for bound in bounds_iter {
@@ -670,6 +685,33 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr
670685

671686
pub fn maybe_resolve_path(&self, p: &syn::Path, generics: Option<&GenericTypes>) -> Option<String> {
672687
self.maybe_resolve_imported_path(p, generics).map(|mut path| {
688+
if path == "core::ops::Deref" || path == "core::ops::DerefMut" {
689+
let last_seg = p.segments.last().unwrap();
690+
if let syn::PathArguments::AngleBracketed(args) = &last_seg.arguments {
691+
assert_eq!(args.args.len(), 1);
692+
if let syn::GenericArgument::Binding(binding) = &args.args[0] {
693+
if let syn::Type::Path(p) = &binding.ty {
694+
if let Some(inner_ty) = self.maybe_resolve_path(&p.path, generics) {
695+
let mut module_riter = inner_ty.rsplitn(2, "::");
696+
let ty_ident = module_riter.next().unwrap();
697+
let module_name = module_riter.next().unwrap();
698+
let module = self.library.modules.get(module_name).unwrap();
699+
for item in module.items.iter() {
700+
match item {
701+
syn::Item::Trait(t) => {
702+
if t.ident == ty_ident {
703+
path = inner_ty;
704+
break;
705+
}
706+
},
707+
_ => {}
708+
}
709+
}
710+
}
711+
} else { unimplemented!(); }
712+
} else { unimplemented!(); }
713+
}
714+
}
673715
loop {
674716
// Now that we've resolved the path to the path as-imported, check whether the path
675717
// is actually a pub(.*) use statement and map it to the real path.

0 commit comments

Comments
 (0)