Skip to content

Commit f81cf4f

Browse files
rustdoc + rustdoc-json support for non_lifetime_binders
1 parent 375d5ac commit f81cf4f

File tree

7 files changed

+72
-29
lines changed

7 files changed

+72
-29
lines changed

src/librustdoc/clean/mod.rs

+3-14
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ use rustc_span::hygiene::{AstPass, MacroKind};
3131
use rustc_span::symbol::{kw, sym, Ident, Symbol};
3232
use rustc_span::{self, ExpnKind};
3333

34-
use std::assert_matches::assert_matches;
3534
use std::collections::hash_map::Entry;
3635
use std::collections::BTreeMap;
3736
use std::default::Default;
@@ -269,15 +268,7 @@ fn clean_where_predicate<'tcx>(
269268
let bound_params = wbp
270269
.bound_generic_params
271270
.iter()
272-
.map(|param| {
273-
// Higher-ranked params must be lifetimes.
274-
// Higher-ranked lifetimes can't have bounds.
275-
assert_matches!(
276-
param,
277-
hir::GenericParam { kind: hir::GenericParamKind::Lifetime { .. }, .. }
278-
);
279-
Lifetime(param.name.ident().name)
280-
})
271+
.map(|param| clean_generic_param(cx, None, param))
281272
.collect();
282273
WherePredicate::BoundPredicate {
283274
ty: clean_ty(wbp.bounded_ty, cx),
@@ -409,7 +400,7 @@ fn clean_projection_predicate<'tcx>(
409400
.collect_referenced_late_bound_regions(&pred)
410401
.into_iter()
411402
.filter_map(|br| match br {
412-
ty::BrNamed(_, name) if br.is_named() => Some(Lifetime(name)),
403+
ty::BrNamed(_, name) if br.is_named() => Some(GenericParamDef::lifetime(name)),
413404
_ => None,
414405
})
415406
.collect();
@@ -507,7 +498,6 @@ fn clean_generic_param_def<'tcx>(
507498
ty::GenericParamDefKind::Const { has_default } => (
508499
def.name,
509500
GenericParamDefKind::Const {
510-
did: def.def_id,
511501
ty: Box::new(clean_middle_ty(
512502
ty::Binder::dummy(
513503
cx.tcx
@@ -577,7 +567,6 @@ fn clean_generic_param<'tcx>(
577567
hir::GenericParamKind::Const { ty, default } => (
578568
param.name.ident().name,
579569
GenericParamDefKind::Const {
580-
did: param.def_id.to_def_id(),
581570
ty: Box::new(clean_ty(ty, cx)),
582571
default: default
583572
.map(|ct| Box::new(ty::Const::from_anon_const(cx.tcx, ct.def_id).to_string())),
@@ -830,7 +819,7 @@ fn clean_ty_generics<'tcx>(
830819
p.get_bound_params()
831820
.into_iter()
832821
.flatten()
833-
.map(|param| GenericParamDef::lifetime(param.0))
822+
.cloned()
834823
.collect(),
835824
));
836825
}

src/librustdoc/clean/simplify.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> ThinVec<WP
4949
equalities.retain(|(lhs, rhs, bound_params)| {
5050
let Some((ty, trait_did, name)) = lhs.projection() else { return true; };
5151
let Some((bounds, _)) = tybounds.get_mut(ty) else { return true };
52-
let bound_params = bound_params
53-
.into_iter()
54-
.map(|param| clean::GenericParamDef::lifetime(param.0))
55-
.collect();
56-
merge_bounds(cx, bounds, bound_params, trait_did, name, rhs)
52+
merge_bounds(cx, bounds, bound_params.clone(), trait_did, name, rhs)
5753
});
5854

5955
// And finally, let's reassemble everything

src/librustdoc/clean/types.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1213,9 +1213,9 @@ impl Lifetime {
12131213

12141214
#[derive(Clone, Debug)]
12151215
pub(crate) enum WherePredicate {
1216-
BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<Lifetime> },
1216+
BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<GenericParamDef> },
12171217
RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
1218-
EqPredicate { lhs: Box<Type>, rhs: Box<Term>, bound_params: Vec<Lifetime> },
1218+
EqPredicate { lhs: Box<Type>, rhs: Box<Term>, bound_params: Vec<GenericParamDef> },
12191219
}
12201220

12211221
impl WherePredicate {
@@ -1227,7 +1227,7 @@ impl WherePredicate {
12271227
}
12281228
}
12291229

1230-
pub(crate) fn get_bound_params(&self) -> Option<&[Lifetime]> {
1230+
pub(crate) fn get_bound_params(&self) -> Option<&[GenericParamDef]> {
12311231
match self {
12321232
Self::BoundPredicate { bound_params, .. } | Self::EqPredicate { bound_params, .. } => {
12331233
Some(bound_params)
@@ -1241,7 +1241,7 @@ impl WherePredicate {
12411241
pub(crate) enum GenericParamDefKind {
12421242
Lifetime { outlives: Vec<Lifetime> },
12431243
Type { did: DefId, bounds: Vec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
1244-
Const { did: DefId, ty: Box<Type>, default: Option<Box<String>> },
1244+
Const { ty: Box<Type>, default: Option<Box<String>> },
12451245
}
12461246

12471247
impl GenericParamDefKind {

src/librustdoc/html/format.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -309,13 +309,13 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
309309
write!(
310310
f,
311311
"for<{:#}> {ty_cx:#}: {generic_bounds:#}",
312-
comma_sep(bound_params.iter().map(|lt| lt.print()), true)
312+
comma_sep(bound_params.iter().map(|lt| lt.print(cx)), true)
313313
)
314314
} else {
315315
write!(
316316
f,
317317
"for&lt;{}&gt; {ty_cx}: {generic_bounds}",
318-
comma_sep(bound_params.iter().map(|lt| lt.print()), true)
318+
comma_sep(bound_params.iter().map(|lt| lt.print(cx)), true)
319319
)
320320
}
321321
}

src/librustdoc/json/conversions.rs

+30-4
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind {
456456
default: default.map(|x| (*x).into_tcx(tcx)),
457457
synthetic,
458458
},
459-
Const { did: _, ty, default } => GenericParamDefKind::Const {
459+
Const { ty, default } => GenericParamDefKind::Const {
460460
type_: (*ty).into_tcx(tcx),
461461
default: default.map(|x| *x),
462462
},
@@ -473,9 +473,35 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
473473
bounds: bounds.into_tcx(tcx),
474474
generic_params: bound_params
475475
.into_iter()
476-
.map(|x| GenericParamDef {
477-
name: x.0.to_string(),
478-
kind: GenericParamDefKind::Lifetime { outlives: vec![] },
476+
.map(|x| {
477+
let name = x.name.to_string();
478+
let kind = match x.kind {
479+
clean::GenericParamDefKind::Lifetime { outlives } => {
480+
GenericParamDefKind::Lifetime {
481+
outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(),
482+
}
483+
}
484+
clean::GenericParamDefKind::Type {
485+
did: _,
486+
bounds,
487+
default,
488+
synthetic,
489+
} => GenericParamDefKind::Type {
490+
bounds: bounds
491+
.into_iter()
492+
.map(|bound| bound.into_tcx(tcx))
493+
.collect(),
494+
default: default.map(|ty| (*ty).into_tcx(tcx)),
495+
synthetic,
496+
},
497+
clean::GenericParamDefKind::Const { ty, default } => {
498+
GenericParamDefKind::Const {
499+
type_: (*ty).into_tcx(tcx),
500+
default: default.map(|d| *d),
501+
}
502+
}
503+
};
504+
GenericParamDef { name, kind }
479505
})
480506
.collect(),
481507
},
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// ignore-tidy-linelength
2+
3+
#![feature(non_lifetime_binders)]
4+
#![allow(incomplete_features)]
5+
6+
#![no_core]
7+
#![feature(lang_items, no_core)]
8+
9+
#[lang = "sized"]
10+
pub trait Sized {}
11+
12+
pub trait Trait {}
13+
14+
pub struct Wrapper<T_, const N_: usize>([T_; N_]);
15+
16+
// @count "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[*]" 3
17+
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[0].name" \"\'a\"
18+
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
19+
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[1].name" \"T\"
20+
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[1].kind" '{ "type": { "bounds": [], "default": null, "synthetic": false } }'
21+
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[2].name" \"N\"
22+
// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[2].kind" '{ "const": { "type": { "kind": "primitive", "inner": "usize" }, "default": null } }'
23+
pub fn foo() where for<'a, T, const N: usize> &'a Wrapper<T, N>: Trait {}

tests/rustdoc/non_lifetime_binders.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(non_lifetime_binders)]
2+
#![allow(incomplete_features)]
3+
4+
pub trait Trait {}
5+
6+
pub struct Wrapper<T, const N: usize>([T; N]);
7+
8+
// @has non_lifetime_binders/fn.foo.html '//pre' "fn foo()where for<'a, T, const N: usize> &'a Wrapper<T, N>: Trait"
9+
pub fn foo() where for<'a, T, const N: usize> &'a Wrapper<T, N>: Trait {}

0 commit comments

Comments
 (0)