diff options
| author | Michael Goulet <michael@errs.io> | 2022-02-14 18:14:38 -0800 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2022-02-27 21:36:29 -0800 |
| commit | ca6e06efba2201da6be9d48f3f922fbb4e90af5f (patch) | |
| tree | d589db449ecfe4427c7dee2f447ec7942f44140d /src/librustdoc/clean | |
| parent | 8a0c2c4e83c216811d96a4a5af9987431b75bd6f (diff) | |
| download | rust-ca6e06efba2201da6be9d48f3f922fbb4e90af5f.tar.gz rust-ca6e06efba2201da6be9d48f3f922fbb4e90af5f.zip | |
make GATs print properly in traits
Diffstat (limited to 'src/librustdoc/clean')
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 70 | ||||
| -rw-r--r-- | src/librustdoc/clean/types.rs | 4 |
2 files changed, 49 insertions, 25 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e0e641c2f9b..2864f69756b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -985,9 +985,10 @@ impl Clean<Item> for hir::TraitItem<'_> { TyMethodItem(t) } hir::TraitItemKind::Type(bounds, ref default) => { + let generics = self.generics.clean(cx); let bounds = bounds.iter().filter_map(|x| x.clean(cx)).collect(); let default = default.map(|t| t.clean(cx)); - AssocTypeItem(bounds, default) + AssocTypeItem(Box::new(generics), bounds, default) } }; let what_rustc_thinks = @@ -1138,32 +1139,55 @@ impl Clean<Item> for ty::AssocItem { if let ty::TraitContainer(_) = self.container { let bounds = tcx.explicit_item_bounds(self.def_id); let predicates = ty::GenericPredicates { parent: None, predicates: bounds }; - let generics = clean_ty_generics(cx, tcx.generics_of(self.def_id), predicates); + let mut generics = + clean_ty_generics(cx, tcx.generics_of(self.def_id), predicates); + // Filter out the bounds that are (likely?) directly attached to the associated type, + // as opposed to being located in the where clause. let mut bounds = generics .where_predicates - .iter() - .filter_map(|pred| { - let (name, self_type, trait_, bounds) = match *pred { - WherePredicate::BoundPredicate { - ty: QPath { ref name, ref self_type, ref trait_, .. }, - ref bounds, - .. - } => (name, self_type, trait_, bounds), - _ => return None, - }; - if *name != my_name { - return None; - } - if trait_.def_id() != self.container.id() { - return None; + .drain_filter(|pred| match *pred { + WherePredicate::BoundPredicate { + ty: QPath { name, ref self_type, ref trait_, .. }, + .. + } => { + if name != my_name { + return false; + } + if trait_.def_id() != self.container.id() { + return false; + } + match **self_type { + Generic(ref s) if *s == kw::SelfUpper => {} + _ => return false, + } + match &assoc.args { + GenericArgs::AngleBracketed { args, bindings } => { + if !bindings.is_empty() + || generics + .params + .iter() + .zip(args) + .any(|(param, arg)| !param_eq_arg(param, arg)) + { + return false; + } + } + GenericArgs::Parenthesized { .. } => { + // The only time this happens is if we're inside the rustdoc for Fn(), + // which only has one associated type, which is not a GAT, so whatever. + } + } + true } - match **self_type { - Generic(ref s) if *s == kw::SelfUpper => {} - _ => return None, + _ => false, + }) + .flat_map(|pred| { + if let WherePredicate::BoundPredicate { bounds, .. } = pred { + bounds + } else { + unreachable!() } - Some(bounds) }) - .flat_map(|i| i.iter().cloned()) .collect::<Vec<_>>(); // Our Sized/?Sized bound didn't get handled when creating the generics // because we didn't actually get our whole set of bounds until just now @@ -1183,7 +1207,7 @@ impl Clean<Item> for ty::AssocItem { None }; - AssocTypeItem(bounds, ty.map(|t| t.clean(cx))) + AssocTypeItem(Box::new(generics), bounds, ty.map(|t| t.clean(cx))) } else { // FIXME: when could this happen? Associated items in inherent impls? let type_ = tcx.type_of(self.def_id).clean(cx); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 467a6940628..3f40385f9b9 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -683,7 +683,7 @@ crate enum ItemKind { /// /// The bounds may be non-empty if there is a `where` clause. /// The `Option<Type>` is the default concrete type (e.g. `trait Trait { type Target = usize; }`) - AssocTypeItem(Vec<GenericBound>, Option<Type>), + AssocTypeItem(Box<Generics>, Vec<GenericBound>, Option<Type>), /// An item that has been stripped by a rustdoc pass StrippedItem(Box<ItemKind>), KeywordItem(Symbol), @@ -721,7 +721,7 @@ impl ItemKind { | ProcMacroItem(_) | PrimitiveItem(_) | AssocConstItem(_, _) - | AssocTypeItem(_, _) + | AssocTypeItem(..) | StrippedItem(_) | KeywordItem(_) => [].iter(), } |
