Skip to content

Commit 831ae3c

Browse files
committed
Auto merge of rust-lang#84814 - Stupremee:properly-render-hrtbs, r=GuillaumeGomez
Properly render HRTBs ```rust pub fn test<T>() where for<'a> &'a T: Iterator, {} ``` This will now render properly including the `for<'a>` ![image](https://user-images.githubusercontent.com/39732259/116808426-fe6ce600-ab38-11eb-9452-f33f554fbb8e.png) I do not know if this covers all cases, it only covers everything that I could think of that includes `for` and lifetimes in where bounds. Also someone need to mentor me on how to add a proper rustdoc test for this. Resolves rust-lang#78482
2 parents 4819719 + 4ea2748 commit 831ae3c

File tree

12 files changed

+233
-118
lines changed

12 files changed

+233
-118
lines changed

src/librustdoc/clean/auto_trait.rs

+7-11
Original file line numberDiff line numberDiff line change
@@ -353,12 +353,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
353353
let (poly_trait, output) =
354354
(data.0.as_ref().expect("as_ref failed").clone(), data.1.as_ref().cloned());
355355
let new_ty = match poly_trait.trait_ {
356-
Type::ResolvedPath {
357-
ref path,
358-
ref param_names,
359-
ref did,
360-
ref is_generic,
361-
} => {
356+
Type::ResolvedPath { ref path, ref did, ref is_generic } => {
362357
let mut new_path = path.clone();
363358
let last_segment =
364359
new_path.segments.pop().expect("segments were empty");
@@ -395,7 +390,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
395390

396391
Type::ResolvedPath {
397392
path: new_path,
398-
param_names: param_names.clone(),
399393
did: *did,
400394
is_generic: *is_generic,
401395
}
@@ -414,7 +408,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
414408
let mut bounds_vec = bounds.into_iter().collect();
415409
self.sort_where_bounds(&mut bounds_vec);
416410

417-
Some(WherePredicate::BoundPredicate { ty, bounds: bounds_vec })
411+
Some(WherePredicate::BoundPredicate {
412+
ty,
413+
bounds: bounds_vec,
414+
bound_params: Vec::new(),
415+
})
418416
})
419417
.chain(
420418
lifetime_to_bounds.into_iter().filter(|&(_, ref bounds)| !bounds.is_empty()).map(
@@ -492,7 +490,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
492490
}
493491
let p = p.unwrap();
494492
match p {
495-
WherePredicate::BoundPredicate { ty, mut bounds } => {
493+
WherePredicate::BoundPredicate { ty, mut bounds, .. } => {
496494
// Writing a projection trait bound of the form
497495
// <T as Trait>::Name : ?Sized
498496
// is illegal, because ?Sized bounds can only
@@ -566,7 +564,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
566564
match **trait_ {
567565
Type::ResolvedPath {
568566
path: ref trait_path,
569-
ref param_names,
570567
ref did,
571568
ref is_generic,
572569
} => {
@@ -613,7 +610,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
613610
PolyTrait {
614611
trait_: Type::ResolvedPath {
615612
path: new_trait_path,
616-
param_names: param_names.clone(),
617613
did: *did,
618614
is_generic: *is_generic,
619615
},

src/librustdoc/clean/inline.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,11 @@ fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::Item
583583
fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics {
584584
for pred in &mut g.where_predicates {
585585
match *pred {
586-
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref mut bounds }
587-
if *s == kw::SelfUpper =>
588-
{
586+
clean::WherePredicate::BoundPredicate {
587+
ty: clean::Generic(ref s),
588+
ref mut bounds,
589+
..
590+
} if *s == kw::SelfUpper => {
589591
bounds.retain(|bound| match *bound {
590592
clean::GenericBound::TraitBound(
591593
clean::PolyTrait { trait_: clean::ResolvedPath { did, .. }, .. },
@@ -608,6 +610,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
608610
..
609611
},
610612
ref bounds,
613+
..
611614
} => !(bounds.is_empty() || *s == kw::SelfUpper && did == trait_did),
612615
_ => true,
613616
});
@@ -622,7 +625,7 @@ fn separate_supertrait_bounds(
622625
) -> (clean::Generics, Vec<clean::GenericBound>) {
623626
let mut ty_bounds = Vec::new();
624627
g.where_predicates.retain(|pred| match *pred {
625-
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds }
628+
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds, .. }
626629
if *s == kw::SelfUpper =>
627630
{
628631
ty_bounds.extend(bounds.iter().cloned());

src/librustdoc/clean/mod.rs

+35-49
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
180180

181181
debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs);
182182

183-
ResolvedPath { path, param_names: None, did: trait_ref.def_id, is_generic: false }
183+
ResolvedPath { path, did: trait_ref.def_id, is_generic: false }
184184
}
185185
}
186186

@@ -330,6 +330,7 @@ impl Clean<WherePredicate> for hir::WherePredicate<'_> {
330330
hir::WherePredicate::BoundPredicate(ref wbp) => WherePredicate::BoundPredicate {
331331
ty: wbp.bounded_ty.clean(cx),
332332
bounds: wbp.bounds.clean(cx),
333+
bound_params: wbp.bound_generic_params.into_iter().map(|x| x.clean(cx)).collect(),
333334
},
334335

335336
hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
@@ -370,6 +371,7 @@ impl<'a> Clean<WherePredicate> for ty::PolyTraitPredicate<'a> {
370371
WherePredicate::BoundPredicate {
371372
ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
372373
bounds: vec![poly_trait_ref.clean(cx)],
374+
bound_params: Vec::new(),
373375
}
374376
}
375377
}
@@ -402,6 +404,7 @@ impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty:
402404
Some(WherePredicate::BoundPredicate {
403405
ty: ty.clean(cx),
404406
bounds: vec![GenericBound::Outlives(lt.clean(cx).expect("failed to clean lifetimes"))],
407+
bound_params: Vec::new(),
405408
})
406409
}
407410
}
@@ -567,7 +570,9 @@ impl Clean<Generics> for hir::Generics<'_> {
567570
// to where predicates when such cases occur.
568571
for where_pred in &mut generics.where_predicates {
569572
match *where_pred {
570-
WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
573+
WherePredicate::BoundPredicate {
574+
ty: Generic(ref name), ref mut bounds, ..
575+
} => {
571576
if bounds.is_empty() {
572577
for param in &mut generics.params {
573578
match param.kind {
@@ -721,7 +726,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
721726
// handled in cleaning associated types
722727
let mut sized_params = FxHashSet::default();
723728
where_predicates.retain(|pred| match *pred {
724-
WP::BoundPredicate { ty: Generic(ref g), ref bounds } => {
729+
WP::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => {
725730
if bounds.iter().any(|b| b.is_sized_bound(cx)) {
726731
sized_params.insert(*g);
727732
false
@@ -741,6 +746,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
741746
where_predicates.push(WP::BoundPredicate {
742747
ty: Type::Generic(tp.name),
743748
bounds: vec![GenericBound::maybe_sized(cx)],
749+
bound_params: Vec::new(),
744750
})
745751
}
746752
}
@@ -1117,6 +1123,7 @@ impl Clean<Item> for ty::AssocItem {
11171123
WherePredicate::BoundPredicate {
11181124
ty: QPath { ref name, ref self_type, ref trait_, .. },
11191125
ref bounds,
1126+
..
11201127
} => (name, self_type, trait_, bounds),
11211128
_ => return None,
11221129
};
@@ -1371,24 +1378,9 @@ impl Clean<Type> for hir::Ty<'_> {
13711378
}
13721379
TyKind::Path(_) => clean_qpath(&self, cx),
13731380
TyKind::TraitObject(ref bounds, ref lifetime, _) => {
1374-
match bounds[0].clean(cx).trait_ {
1375-
ResolvedPath { path, param_names: None, did, is_generic } => {
1376-
let mut bounds: Vec<self::GenericBound> = bounds[1..]
1377-
.iter()
1378-
.map(|bound| {
1379-
self::GenericBound::TraitBound(
1380-
bound.clean(cx),
1381-
hir::TraitBoundModifier::None,
1382-
)
1383-
})
1384-
.collect();
1385-
if !lifetime.is_elided() {
1386-
bounds.push(self::GenericBound::Outlives(lifetime.clean(cx)));
1387-
}
1388-
ResolvedPath { path, param_names: Some(bounds), did, is_generic }
1389-
}
1390-
_ => Infer, // shouldn't happen
1391-
}
1381+
let bounds = bounds.iter().map(|bound| bound.clean(cx)).collect();
1382+
let lifetime = if !lifetime.is_elided() { Some(lifetime.clean(cx)) } else { None };
1383+
DynTrait(bounds, lifetime)
13921384
}
13931385
TyKind::BareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
13941386
TyKind::Infer | TyKind::Err => Infer,
@@ -1471,7 +1463,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
14711463
};
14721464
inline::record_extern_fqn(cx, did, kind);
14731465
let path = external_path(cx, cx.tcx.item_name(did), None, false, vec![], substs);
1474-
ResolvedPath { path, param_names: None, did, is_generic: false }
1466+
ResolvedPath { path, did, is_generic: false }
14751467
}
14761468
ty::Foreign(did) => {
14771469
inline::record_extern_fqn(cx, did, ItemType::ForeignType);
@@ -1483,7 +1475,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
14831475
vec![],
14841476
InternalSubsts::empty(),
14851477
);
1486-
ResolvedPath { path, param_names: None, did, is_generic: false }
1478+
ResolvedPath { path, did, is_generic: false }
14871479
}
14881480
ty::Dynamic(ref obj, ref reg) => {
14891481
// HACK: pick the first `did` as the `did` of the trait object. Someone
@@ -1501,28 +1493,19 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
15011493

15021494
inline::record_extern_fqn(cx, did, ItemType::Trait);
15031495

1504-
let mut param_names = vec![];
1505-
if let Some(b) = reg.clean(cx) {
1506-
param_names.push(GenericBound::Outlives(b));
1507-
}
1496+
let lifetime = reg.clean(cx);
1497+
let mut bounds = vec![];
1498+
15081499
for did in dids {
15091500
let empty = cx.tcx.intern_substs(&[]);
15101501
let path =
15111502
external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
15121503
inline::record_extern_fqn(cx, did, ItemType::Trait);
1513-
let bound = GenericBound::TraitBound(
1514-
PolyTrait {
1515-
trait_: ResolvedPath {
1516-
path,
1517-
param_names: None,
1518-
did,
1519-
is_generic: false,
1520-
},
1521-
generic_params: Vec::new(),
1522-
},
1523-
hir::TraitBoundModifier::None,
1524-
);
1525-
param_names.push(bound);
1504+
let bound = PolyTrait {
1505+
trait_: ResolvedPath { path, did, is_generic: false },
1506+
generic_params: Vec::new(),
1507+
};
1508+
bounds.push(bound);
15261509
}
15271510

15281511
let mut bindings = vec![];
@@ -1535,7 +1518,15 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
15351518

15361519
let path =
15371520
external_path(cx, cx.tcx.item_name(did), Some(did), false, bindings, substs);
1538-
ResolvedPath { path, param_names: Some(param_names), did, is_generic: false }
1521+
bounds.insert(
1522+
0,
1523+
PolyTrait {
1524+
trait_: ResolvedPath { path, did, is_generic: false },
1525+
generic_params: Vec::new(),
1526+
},
1527+
);
1528+
1529+
DynTrait(bounds, lifetime)
15391530
}
15401531
ty::Tuple(ref t) => {
15411532
Tuple(t.iter().map(|t| t.expect_ty()).collect::<Vec<_>>().clean(cx))
@@ -2239,14 +2230,9 @@ impl From<GenericBound> for SimpleBound {
22392230
match bound.clone() {
22402231
GenericBound::Outlives(l) => SimpleBound::Outlives(l),
22412232
GenericBound::TraitBound(t, mod_) => match t.trait_ {
2242-
Type::ResolvedPath { path, param_names, .. } => SimpleBound::TraitBound(
2243-
path.segments,
2244-
param_names.map_or_else(Vec::new, |v| {
2245-
v.iter().map(|p| SimpleBound::from(p.clone())).collect()
2246-
}),
2247-
t.generic_params,
2248-
mod_,
2249-
),
2233+
Type::ResolvedPath { path, .. } => {
2234+
SimpleBound::TraitBound(path.segments, Vec::new(), t.generic_params, mod_)
2235+
}
22502236
_ => panic!("Unexpected bound {:?}", bound),
22512237
},
22522238
}

src/librustdoc/clean/simplify.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,20 @@ use crate::core::DocContext;
2424

2525
crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
2626
// First, partition the where clause into its separate components
27-
let mut params: BTreeMap<_, Vec<_>> = BTreeMap::new();
27+
let mut params: BTreeMap<_, (Vec<_>, Vec<_>)> = BTreeMap::new();
2828
let mut lifetimes = Vec::new();
2929
let mut equalities = Vec::new();
3030
let mut tybounds = Vec::new();
3131

3232
for clause in clauses {
3333
match clause {
34-
WP::BoundPredicate { ty, bounds } => match ty {
35-
clean::Generic(s) => params.entry(s).or_default().extend(bounds),
36-
t => tybounds.push((t, bounds)),
34+
WP::BoundPredicate { ty, bounds, bound_params } => match ty {
35+
clean::Generic(s) => {
36+
let (b, p) = params.entry(s).or_default();
37+
b.extend(bounds);
38+
p.extend(bound_params);
39+
}
40+
t => tybounds.push((t, (bounds, bound_params))),
3741
},
3842
WP::RegionPredicate { lifetime, bounds } => {
3943
lifetimes.push((lifetime, bounds));
@@ -54,7 +58,7 @@ crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
5458
clean::Generic(s) => s,
5559
_ => return true,
5660
};
57-
let bounds = match params.get_mut(generic) {
61+
let (bounds, _) = match params.get_mut(generic) {
5862
Some(bound) => bound,
5963
None => return true,
6064
};
@@ -67,10 +71,16 @@ crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
6771
clauses.extend(
6872
lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }),
6973
);
70-
clauses.extend(
71-
params.into_iter().map(|(k, v)| WP::BoundPredicate { ty: clean::Generic(k), bounds: v }),
72-
);
73-
clauses.extend(tybounds.into_iter().map(|(ty, bounds)| WP::BoundPredicate { ty, bounds }));
74+
clauses.extend(params.into_iter().map(|(k, (bounds, params))| WP::BoundPredicate {
75+
ty: clean::Generic(k),
76+
bounds,
77+
bound_params: params,
78+
}));
79+
clauses.extend(tybounds.into_iter().map(|(ty, (bounds, bound_params))| WP::BoundPredicate {
80+
ty,
81+
bounds,
82+
bound_params,
83+
}));
7484
clauses.extend(equalities.into_iter().map(|(lhs, rhs)| WP::EqPredicate { lhs, rhs }));
7585
clauses
7686
}

src/librustdoc/clean/types.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,7 @@ impl GenericBound {
11681168
inline::record_extern_fqn(cx, did, ItemType::Trait);
11691169
GenericBound::TraitBound(
11701170
PolyTrait {
1171-
trait_: ResolvedPath { path, param_names: None, did, is_generic: false },
1171+
trait_: ResolvedPath { path, did, is_generic: false },
11721172
generic_params: Vec::new(),
11731173
},
11741174
hir::TraitBoundModifier::Maybe,
@@ -1220,7 +1220,7 @@ impl Lifetime {
12201220

12211221
#[derive(Clone, Debug)]
12221222
crate enum WherePredicate {
1223-
BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
1223+
BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<Lifetime> },
12241224
RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
12251225
EqPredicate { lhs: Type, rhs: Type },
12261226
}
@@ -1434,11 +1434,12 @@ crate enum Type {
14341434
/// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
14351435
ResolvedPath {
14361436
path: Path,
1437-
param_names: Option<Vec<GenericBound>>,
14381437
did: DefId,
14391438
/// `true` if is a `T::Name` path for associated types.
14401439
is_generic: bool,
14411440
},
1441+
/// `dyn for<'a> Trait<'a> + Send + 'static`
1442+
DynTrait(Vec<PolyTrait>, Option<Lifetime>),
14421443
/// For parameterized types, so the consumer of the JSON don't go
14431444
/// looking for types which don't exist anywhere.
14441445
Generic(Symbol),
@@ -1625,6 +1626,7 @@ impl Type {
16251626
fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
16261627
let t: PrimitiveType = match *self {
16271628
ResolvedPath { did, .. } => return Some(did.into()),
1629+
DynTrait(ref bounds, _) => return bounds[0].trait_.inner_def_id(cache),
16281630
Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
16291631
BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
16301632
BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache),

0 commit comments

Comments
 (0)