Skip to content

Commit e0162a8

Browse files
committed
rustdoc: Render for<'_> lifetimes in front of where bound
1 parent 312b894 commit e0162a8

File tree

8 files changed

+104
-22
lines changed

8 files changed

+104
-22
lines changed

src/librustdoc/clean/auto_trait.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
414414
let mut bounds_vec = bounds.into_iter().collect();
415415
self.sort_where_bounds(&mut bounds_vec);
416416

417-
Some(WherePredicate::BoundPredicate { ty, bounds: bounds_vec })
417+
Some(WherePredicate::BoundPredicate {
418+
ty,
419+
bounds: bounds_vec,
420+
bound_params: Vec::new(),
421+
})
418422
})
419423
.chain(
420424
lifetime_to_bounds.into_iter().filter(|&(_, ref bounds)| !bounds.is_empty()).map(
@@ -492,7 +496,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
492496
}
493497
let p = p.unwrap();
494498
match p {
495-
WherePredicate::BoundPredicate { ty, mut bounds } => {
499+
WherePredicate::BoundPredicate { ty, mut bounds, .. } => {
496500
// Writing a projection trait bound of the form
497501
// <T as Trait>::Name : ?Sized
498502
// is illegal, because ?Sized bounds can only

src/librustdoc/clean/inline.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -566,9 +566,11 @@ fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::Item
566566
fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics {
567567
for pred in &mut g.where_predicates {
568568
match *pred {
569-
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref mut bounds }
570-
if *s == kw::SelfUpper =>
571-
{
569+
clean::WherePredicate::BoundPredicate {
570+
ty: clean::Generic(ref s),
571+
ref mut bounds,
572+
..
573+
} if *s == kw::SelfUpper => {
572574
bounds.retain(|bound| match *bound {
573575
clean::GenericBound::TraitBound(
574576
clean::PolyTrait { trait_: clean::ResolvedPath { did, .. }, .. },
@@ -591,6 +593,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
591593
..
592594
},
593595
ref bounds,
596+
..
594597
} => !(bounds.is_empty() || *s == kw::SelfUpper && did == trait_did),
595598
_ => true,
596599
});
@@ -605,7 +608,7 @@ fn separate_supertrait_bounds(
605608
) -> (clean::Generics, Vec<clean::GenericBound>) {
606609
let mut ty_bounds = Vec::new();
607610
g.where_predicates.retain(|pred| match *pred {
608-
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds }
611+
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds, .. }
609612
if *s == kw::SelfUpper =>
610613
{
611614
ty_bounds.extend(bounds.iter().cloned());

src/librustdoc/clean/mod.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -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
};

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ impl Lifetime {
11931193

11941194
#[derive(Clone, Debug)]
11951195
crate enum WherePredicate {
1196-
BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
1196+
BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<Lifetime> },
11971197
RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
11981198
EqPredicate { lhs: Type, rhs: Type },
11991199
}

src/librustdoc/html/format.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -249,17 +249,33 @@ crate fn print_where_clause<'a, 'tcx: 'a>(
249249
}
250250

251251
match pred {
252-
clean::WherePredicate::BoundPredicate { ty, bounds } => {
252+
clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
253253
let bounds = bounds;
254+
let for_prefix = match bound_params.len() {
255+
0 => String::new(),
256+
_ if f.alternate() => {
257+
format!(
258+
"for<{:#}> ",
259+
comma_sep(bound_params.iter().map(|lt| lt.print()))
260+
)
261+
}
262+
_ => format!(
263+
"for&lt;{}&gt; ",
264+
comma_sep(bound_params.iter().map(|lt| lt.print()))
265+
),
266+
};
267+
254268
if f.alternate() {
255269
clause.push_str(&format!(
256-
"{:#}: {:#}",
270+
"{}{:#}: {:#}",
271+
for_prefix,
257272
ty.print(cx),
258273
print_generic_bounds(bounds, cx)
259274
));
260275
} else {
261276
clause.push_str(&format!(
262-
"{}: {}",
277+
"{}{}: {}",
278+
for_prefix,
263279
ty.print(cx),
264280
print_generic_bounds(bounds, cx)
265281
));

src/librustdoc/json/conversions.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,10 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
328328
fn from_tcx(predicate: clean::WherePredicate, tcx: TyCtxt<'_>) -> Self {
329329
use clean::WherePredicate::*;
330330
match predicate {
331-
BoundPredicate { ty, bounds } => WherePredicate::BoundPredicate {
331+
BoundPredicate { ty, bounds, .. } => WherePredicate::BoundPredicate {
332332
ty: ty.into_tcx(tcx),
333333
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
334+
// FIXME: add `bound_params` to rustdoc-json-params?
334335
},
335336
RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate {
336337
lifetime: lifetime.0.to_string(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#![crate_name = "foo"]
2+
3+
trait A<'x> {}
4+
5+
// @has foo/fn.test1.html
6+
// @has - '//pre' "pub fn test1<T>() where for<'a> &'a T: Iterator,"
7+
pub fn test1<T>()
8+
where
9+
for<'a> &'a T: Iterator,
10+
{
11+
}
12+
13+
// @has foo/fn.test2.html
14+
// @has - '//pre' "pub fn test2<T>() where for<'a, 'b> &'a T: A<'b>,"
15+
pub fn test2<T>()
16+
where
17+
for<'a, 'b> &'a T: A<'b>,
18+
{
19+
}
20+
21+
// @has foo/fn.test3.html
22+
// @has - '//pre' "pub fn test3<F>() where F: for<'a, 'b> Fn(&'a u8, &'b u8),"
23+
pub fn test3<F>()
24+
where
25+
F: for<'a, 'b> Fn(&'a u8, &'b u8),
26+
{
27+
}
28+
29+
// @has foo/struct.Foo.html
30+
pub struct Foo<'a> {
31+
_x: &'a u8,
32+
}
33+
34+
impl<'a> Foo<'a> {
35+
// @has - '//code' "pub fn bar<T>() where T: A<'a>,"
36+
pub fn bar<T>()
37+
where
38+
T: A<'a>,
39+
{
40+
}
41+
}

0 commit comments

Comments
 (0)