mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
rustdoc: Render for<'_>
lifetimes in front of where bound
This commit is contained in:
parent
312b894cc1
commit
e0162a8a56
@ -414,7 +414,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||
let mut bounds_vec = bounds.into_iter().collect();
|
||||
self.sort_where_bounds(&mut bounds_vec);
|
||||
|
||||
Some(WherePredicate::BoundPredicate { ty, bounds: bounds_vec })
|
||||
Some(WherePredicate::BoundPredicate {
|
||||
ty,
|
||||
bounds: bounds_vec,
|
||||
bound_params: Vec::new(),
|
||||
})
|
||||
})
|
||||
.chain(
|
||||
lifetime_to_bounds.into_iter().filter(|&(_, ref bounds)| !bounds.is_empty()).map(
|
||||
@ -492,7 +496,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||
}
|
||||
let p = p.unwrap();
|
||||
match p {
|
||||
WherePredicate::BoundPredicate { ty, mut bounds } => {
|
||||
WherePredicate::BoundPredicate { ty, mut bounds, .. } => {
|
||||
// Writing a projection trait bound of the form
|
||||
// <T as Trait>::Name : ?Sized
|
||||
// is illegal, because ?Sized bounds can only
|
||||
|
@ -566,9 +566,11 @@ fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::Item
|
||||
fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics {
|
||||
for pred in &mut g.where_predicates {
|
||||
match *pred {
|
||||
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref mut bounds }
|
||||
if *s == kw::SelfUpper =>
|
||||
{
|
||||
clean::WherePredicate::BoundPredicate {
|
||||
ty: clean::Generic(ref s),
|
||||
ref mut bounds,
|
||||
..
|
||||
} if *s == kw::SelfUpper => {
|
||||
bounds.retain(|bound| match *bound {
|
||||
clean::GenericBound::TraitBound(
|
||||
clean::PolyTrait { trait_: clean::ResolvedPath { did, .. }, .. },
|
||||
@ -591,6 +593,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
|
||||
..
|
||||
},
|
||||
ref bounds,
|
||||
..
|
||||
} => !(bounds.is_empty() || *s == kw::SelfUpper && did == trait_did),
|
||||
_ => true,
|
||||
});
|
||||
@ -605,7 +608,7 @@ fn separate_supertrait_bounds(
|
||||
) -> (clean::Generics, Vec<clean::GenericBound>) {
|
||||
let mut ty_bounds = Vec::new();
|
||||
g.where_predicates.retain(|pred| match *pred {
|
||||
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds }
|
||||
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds, .. }
|
||||
if *s == kw::SelfUpper =>
|
||||
{
|
||||
ty_bounds.extend(bounds.iter().cloned());
|
||||
|
@ -330,6 +330,7 @@ impl Clean<WherePredicate> for hir::WherePredicate<'_> {
|
||||
hir::WherePredicate::BoundPredicate(ref wbp) => WherePredicate::BoundPredicate {
|
||||
ty: wbp.bounded_ty.clean(cx),
|
||||
bounds: wbp.bounds.clean(cx),
|
||||
bound_params: wbp.bound_generic_params.into_iter().map(|x| x.clean(cx)).collect(),
|
||||
},
|
||||
|
||||
hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
|
||||
@ -370,6 +371,7 @@ impl<'a> Clean<WherePredicate> for ty::PolyTraitPredicate<'a> {
|
||||
WherePredicate::BoundPredicate {
|
||||
ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
|
||||
bounds: vec![poly_trait_ref.clean(cx)],
|
||||
bound_params: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -402,6 +404,7 @@ impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty:
|
||||
Some(WherePredicate::BoundPredicate {
|
||||
ty: ty.clean(cx),
|
||||
bounds: vec![GenericBound::Outlives(lt.clean(cx).expect("failed to clean lifetimes"))],
|
||||
bound_params: Vec::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -567,7 +570,9 @@ impl Clean<Generics> for hir::Generics<'_> {
|
||||
// to where predicates when such cases occur.
|
||||
for where_pred in &mut generics.where_predicates {
|
||||
match *where_pred {
|
||||
WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
|
||||
WherePredicate::BoundPredicate {
|
||||
ty: Generic(ref name), ref mut bounds, ..
|
||||
} => {
|
||||
if bounds.is_empty() {
|
||||
for param in &mut generics.params {
|
||||
match param.kind {
|
||||
@ -721,7 +726,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
|
||||
// handled in cleaning associated types
|
||||
let mut sized_params = FxHashSet::default();
|
||||
where_predicates.retain(|pred| match *pred {
|
||||
WP::BoundPredicate { ty: Generic(ref g), ref bounds } => {
|
||||
WP::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => {
|
||||
if bounds.iter().any(|b| b.is_sized_bound(cx)) {
|
||||
sized_params.insert(*g);
|
||||
false
|
||||
@ -741,6 +746,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
|
||||
where_predicates.push(WP::BoundPredicate {
|
||||
ty: Type::Generic(tp.name),
|
||||
bounds: vec![GenericBound::maybe_sized(cx)],
|
||||
bound_params: Vec::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1117,6 +1123,7 @@ impl Clean<Item> for ty::AssocItem {
|
||||
WherePredicate::BoundPredicate {
|
||||
ty: QPath { ref name, ref self_type, ref trait_, .. },
|
||||
ref bounds,
|
||||
..
|
||||
} => (name, self_type, trait_, bounds),
|
||||
_ => return None,
|
||||
};
|
||||
|
@ -24,16 +24,20 @@ use crate::core::DocContext;
|
||||
|
||||
crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
|
||||
// First, partition the where clause into its separate components
|
||||
let mut params: BTreeMap<_, Vec<_>> = BTreeMap::new();
|
||||
let mut params: BTreeMap<_, (Vec<_>, Vec<_>)> = BTreeMap::new();
|
||||
let mut lifetimes = Vec::new();
|
||||
let mut equalities = Vec::new();
|
||||
let mut tybounds = Vec::new();
|
||||
|
||||
for clause in clauses {
|
||||
match clause {
|
||||
WP::BoundPredicate { ty, bounds } => match ty {
|
||||
clean::Generic(s) => params.entry(s).or_default().extend(bounds),
|
||||
t => tybounds.push((t, bounds)),
|
||||
WP::BoundPredicate { ty, bounds, bound_params } => match ty {
|
||||
clean::Generic(s) => {
|
||||
let (b, p) = params.entry(s).or_default();
|
||||
b.extend(bounds);
|
||||
p.extend(bound_params);
|
||||
}
|
||||
t => tybounds.push((t, (bounds, bound_params))),
|
||||
},
|
||||
WP::RegionPredicate { lifetime, bounds } => {
|
||||
lifetimes.push((lifetime, bounds));
|
||||
@ -54,7 +58,7 @@ crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
|
||||
clean::Generic(s) => s,
|
||||
_ => return true,
|
||||
};
|
||||
let bounds = match params.get_mut(generic) {
|
||||
let (bounds, _) = match params.get_mut(generic) {
|
||||
Some(bound) => bound,
|
||||
None => return true,
|
||||
};
|
||||
@ -67,10 +71,16 @@ crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
|
||||
clauses.extend(
|
||||
lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }),
|
||||
);
|
||||
clauses.extend(
|
||||
params.into_iter().map(|(k, v)| WP::BoundPredicate { ty: clean::Generic(k), bounds: v }),
|
||||
);
|
||||
clauses.extend(tybounds.into_iter().map(|(ty, bounds)| WP::BoundPredicate { ty, bounds }));
|
||||
clauses.extend(params.into_iter().map(|(k, (bounds, params))| WP::BoundPredicate {
|
||||
ty: clean::Generic(k),
|
||||
bounds,
|
||||
bound_params: params,
|
||||
}));
|
||||
clauses.extend(tybounds.into_iter().map(|(ty, (bounds, bound_params))| WP::BoundPredicate {
|
||||
ty,
|
||||
bounds,
|
||||
bound_params,
|
||||
}));
|
||||
clauses.extend(equalities.into_iter().map(|(lhs, rhs)| WP::EqPredicate { lhs, rhs }));
|
||||
clauses
|
||||
}
|
||||
|
@ -1193,7 +1193,7 @@ impl Lifetime {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
crate enum WherePredicate {
|
||||
BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
|
||||
BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<Lifetime> },
|
||||
RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
|
||||
EqPredicate { lhs: Type, rhs: Type },
|
||||
}
|
||||
|
@ -249,17 +249,33 @@ crate fn print_where_clause<'a, 'tcx: 'a>(
|
||||
}
|
||||
|
||||
match pred {
|
||||
clean::WherePredicate::BoundPredicate { ty, bounds } => {
|
||||
clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
|
||||
let bounds = bounds;
|
||||
let for_prefix = match bound_params.len() {
|
||||
0 => String::new(),
|
||||
_ if f.alternate() => {
|
||||
format!(
|
||||
"for<{:#}> ",
|
||||
comma_sep(bound_params.iter().map(|lt| lt.print()))
|
||||
)
|
||||
}
|
||||
_ => format!(
|
||||
"for<{}> ",
|
||||
comma_sep(bound_params.iter().map(|lt| lt.print()))
|
||||
),
|
||||
};
|
||||
|
||||
if f.alternate() {
|
||||
clause.push_str(&format!(
|
||||
"{:#}: {:#}",
|
||||
"{}{:#}: {:#}",
|
||||
for_prefix,
|
||||
ty.print(cx),
|
||||
print_generic_bounds(bounds, cx)
|
||||
));
|
||||
} else {
|
||||
clause.push_str(&format!(
|
||||
"{}: {}",
|
||||
"{}{}: {}",
|
||||
for_prefix,
|
||||
ty.print(cx),
|
||||
print_generic_bounds(bounds, cx)
|
||||
));
|
||||
|
@ -328,9 +328,10 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
|
||||
fn from_tcx(predicate: clean::WherePredicate, tcx: TyCtxt<'_>) -> Self {
|
||||
use clean::WherePredicate::*;
|
||||
match predicate {
|
||||
BoundPredicate { ty, bounds } => WherePredicate::BoundPredicate {
|
||||
BoundPredicate { ty, bounds, .. } => WherePredicate::BoundPredicate {
|
||||
ty: ty.into_tcx(tcx),
|
||||
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
|
||||
// FIXME: add `bound_params` to rustdoc-json-params?
|
||||
},
|
||||
RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate {
|
||||
lifetime: lifetime.0.to_string(),
|
||||
|
41
src/test/rustdoc/higher-ranked-trait-bounds.rs
Normal file
41
src/test/rustdoc/higher-ranked-trait-bounds.rs
Normal file
@ -0,0 +1,41 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
trait A<'x> {}
|
||||
|
||||
// @has foo/fn.test1.html
|
||||
// @has - '//pre' "pub fn test1<T>() where for<'a> &'a T: Iterator,"
|
||||
pub fn test1<T>()
|
||||
where
|
||||
for<'a> &'a T: Iterator,
|
||||
{
|
||||
}
|
||||
|
||||
// @has foo/fn.test2.html
|
||||
// @has - '//pre' "pub fn test2<T>() where for<'a, 'b> &'a T: A<'b>,"
|
||||
pub fn test2<T>()
|
||||
where
|
||||
for<'a, 'b> &'a T: A<'b>,
|
||||
{
|
||||
}
|
||||
|
||||
// @has foo/fn.test3.html
|
||||
// @has - '//pre' "pub fn test3<F>() where F: for<'a, 'b> Fn(&'a u8, &'b u8),"
|
||||
pub fn test3<F>()
|
||||
where
|
||||
F: for<'a, 'b> Fn(&'a u8, &'b u8),
|
||||
{
|
||||
}
|
||||
|
||||
// @has foo/struct.Foo.html
|
||||
pub struct Foo<'a> {
|
||||
_x: &'a u8,
|
||||
}
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
// @has - '//code' "pub fn bar<T>() where T: A<'a>,"
|
||||
pub fn bar<T>()
|
||||
where
|
||||
T: A<'a>,
|
||||
{
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user