+
+ let mut ref_types = HashSet::new();
+ for item in $t.items.iter() {
+ if let syn::TraitItem::Type(ref t) = &item {
+ if t.default.is_some() || t.generics.lt_token.is_some() { panic!("10"); }
+ let mut bounds_iter = t.bounds.iter();
+ loop {
+ match bounds_iter.next().unwrap() {
+ syn::TypeParamBound::Trait(tr) => {
+ match $type_resolver.resolve_path(&tr.path, None).as_str() {
+ "core::ops::Deref"|"core::ops::DerefMut"|"std::ops::Deref"|"std::ops::DerefMut" => {
+ // Handle cases like
+ // trait A {
+ // type B;
+ // type C: Deref<Target = Self::B>;
+ // }
+ // by tracking if we have any B's here and making them
+ // the *Ref types below.
+ if let syn::PathArguments::AngleBracketed(args) = &tr.path.segments.iter().last().unwrap().arguments {
+ if let syn::GenericArgument::Binding(bind) = args.args.iter().last().unwrap() {
+ assert_eq!(format!("{}", bind.ident), "Target");
+ if let syn::Type::Path(p) = &bind.ty {
+ assert!(p.qself.is_none());
+ let mut segs = p.path.segments.iter();
+ assert_eq!(format!("{}", segs.next().unwrap().ident), "Self");
+ ref_types.insert(format!("{}", segs.next().unwrap().ident));
+ assert!(segs.next().is_none());
+ } else { panic!(); }
+ }
+ }
+ },
+ _ => {},
+ }
+ break;
+ }
+ syn::TypeParamBound::Lifetime(_) => {},
+ }
+ }
+ }
+ }
+