Skip to content

Commit 7d7a418

Browse files
committed
Auto merge of #121022 - fmease:rustdoc-x-crate-late-bound-lt-src-order, r=<try>
rustdoc: cross-crate re-exports: correctly render late-bound params in source order even if early-bound params are present r? ghost
2 parents fd9bb7f + c19c531 commit 7d7a418

File tree

9 files changed

+76
-35
lines changed

9 files changed

+76
-35
lines changed

src/librustdoc/clean/auto_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ where
334334
match br {
335335
// We only care about named late bound regions, as we need to add them
336336
// to the 'for<>' section
337-
ty::BrNamed(_, name) => Some(GenericParamDef::lifetime(name)),
337+
ty::BrNamed(did, name) => Some(GenericParamDef::lifetime(did, name)),
338338
_ => None,
339339
}
340340
})

src/librustdoc/clean/inline.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,12 @@ fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<c
281281
let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
282282
// NOTE: generics need to be cleaned before the decl!
283283
let mut generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
284-
// FIXME: This does not place parameters in source order (late-bound ones come last)
285284
generics.params.extend(clean_bound_vars(sig.bound_vars()));
285+
// FIXME(fmease): Does this work in the presence of synthetic params (impl-Trait, host effect)?
286+
// FIXME(fmease): Optimization: Don't call def_ident_span on non-lifetime params!
287+
if !sig.bound_vars().is_empty() {
288+
generics.params.sort_by_key(|param| cx.tcx.def_ident_span(param.did).unwrap());
289+
}
286290
let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig);
287291
(generics, decl)
288292
});

src/librustdoc/clean/mod.rs

+19-14
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,6 @@ fn clean_generic_param_def<'tcx>(
525525
(
526526
def.name,
527527
GenericParamDefKind::Type {
528-
did: def.def_id,
529528
bounds: ThinVec::new(), // These are filled in from the where-clauses.
530529
default: default.map(Box::new),
531530
synthetic,
@@ -557,7 +556,7 @@ fn clean_generic_param_def<'tcx>(
557556
),
558557
};
559558

560-
GenericParamDef { name, kind }
559+
GenericParamDef { name, did: def.def_id, kind }
561560
}
562561

563562
fn clean_generic_param<'tcx>(
@@ -596,7 +595,6 @@ fn clean_generic_param<'tcx>(
596595
(
597596
param.name.ident().name,
598597
GenericParamDefKind::Type {
599-
did: param.def_id.to_def_id(),
600598
bounds,
601599
default: default.map(|t| clean_ty(t, cx)).map(Box::new),
602600
synthetic,
@@ -614,7 +612,7 @@ fn clean_generic_param<'tcx>(
614612
),
615613
};
616614

617-
GenericParamDef { name, kind }
615+
GenericParamDef { name, did: param.def_id.to_def_id(), kind }
618616
}
619617

620618
/// Synthetic type-parameters are inserted after normal ones.
@@ -646,8 +644,8 @@ pub(crate) fn clean_generics<'tcx>(
646644
let param = clean_generic_param(cx, Some(gens), param);
647645
match param.kind {
648646
GenericParamDefKind::Lifetime { .. } => unreachable!(),
649-
GenericParamDefKind::Type { did, ref bounds, .. } => {
650-
cx.impl_trait_bounds.insert(did.into(), bounds.to_vec());
647+
GenericParamDefKind::Type { ref bounds, .. } => {
648+
cx.impl_trait_bounds.insert(param.did.into(), bounds.to_vec());
651649
}
652650
GenericParamDefKind::Const { .. } => unreachable!(),
653651
}
@@ -1064,8 +1062,11 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib
10641062
match literal.kind {
10651063
ast::LitKind::Int(a, _) => {
10661064
let gen = func.generics.params.remove(0);
1067-
if let GenericParamDef { name, kind: GenericParamDefKind::Const { ty, .. } } =
1068-
gen
1065+
if let GenericParamDef {
1066+
name,
1067+
kind: GenericParamDefKind::Const { ty, .. },
1068+
..
1069+
} = gen
10691070
{
10701071
func.decl
10711072
.inputs
@@ -1365,8 +1366,12 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
13651366
tcx.generics_of(assoc_item.def_id),
13661367
tcx.explicit_predicates_of(assoc_item.def_id),
13671368
);
1368-
// FIXME: This does not place parameters in source order (late-bound ones come last)
13691369
generics.params.extend(clean_bound_vars(sig.bound_vars()));
1370+
// FIXME(fmease): Does this work in the presence of synthetic params (impl-Trait, host effect)?
1371+
// FIXME(fmease): Optimization: Don't call def_ident_span on non-lifetime params!
1372+
if !sig.bound_vars().is_empty() {
1373+
generics.params.sort_by_key(|param| tcx.def_ident_span(param.did).unwrap());
1374+
}
13701375

13711376
let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig);
13721377

@@ -2192,10 +2197,10 @@ pub(crate) fn clean_middle_ty<'tcx>(
21922197
.iter()
21932198
.flat_map(|pred| pred.bound_vars())
21942199
.filter_map(|var| match var {
2195-
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
2200+
ty::BoundVariableKind::Region(ty::BrNamed(did, name))
21962201
if name != kw::UnderscoreLifetime =>
21972202
{
2198-
Some(GenericParamDef::lifetime(name))
2203+
Some(GenericParamDef::lifetime(did, name))
21992204
}
22002205
_ => None,
22012206
})
@@ -3167,15 +3172,15 @@ fn clean_bound_vars<'tcx>(
31673172
bound_vars
31683173
.into_iter()
31693174
.filter_map(|var| match var {
3170-
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
3175+
ty::BoundVariableKind::Region(ty::BrNamed(did, name))
31713176
if name != kw::UnderscoreLifetime =>
31723177
{
3173-
Some(GenericParamDef::lifetime(name))
3178+
Some(GenericParamDef::lifetime(did, name))
31743179
}
31753180
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(did, name)) => Some(GenericParamDef {
31763181
name,
3182+
did,
31773183
kind: GenericParamDefKind::Type {
3178-
did,
31793184
bounds: ThinVec::new(),
31803185
default: None,
31813186
synthetic: false,

src/librustdoc/clean/simplify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pub(crate) fn move_bounds_to_generic_parameters(generics: &mut clean::Generics)
149149
} else if let WherePredicate::RegionPredicate { lifetime: Lifetime(arg), bounds } =
150150
&mut pred
151151
&& let Some(GenericParamDef {
152-
kind: GenericParamDefKind::Lifetime { outlives: param_bounds },
152+
kind: GenericParamDefKind::Lifetime { outlives: param_bounds, .. },
153153
..
154154
}) = generics.params.iter_mut().find(|param| &param.name == arg)
155155
{

src/librustdoc/clean/types.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1326,7 +1326,7 @@ impl WherePredicate {
13261326
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
13271327
pub(crate) enum GenericParamDefKind {
13281328
Lifetime { outlives: ThinVec<Lifetime> },
1329-
Type { did: DefId, bounds: ThinVec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
1329+
Type { bounds: ThinVec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
13301330
// Option<Box<String>> makes this type smaller than `Option<String>` would.
13311331
Const { ty: Box<Type>, default: Option<Box<String>>, is_host_effect: bool },
13321332
}
@@ -1339,13 +1339,14 @@ impl GenericParamDefKind {
13391339

13401340
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
13411341
pub(crate) struct GenericParamDef {
1342+
pub(crate) did: DefId,
13421343
pub(crate) name: Symbol,
13431344
pub(crate) kind: GenericParamDefKind,
13441345
}
13451346

13461347
impl GenericParamDef {
1347-
pub(crate) fn lifetime(name: Symbol) -> Self {
1348-
Self { name, kind: GenericParamDefKind::Lifetime { outlives: ThinVec::new() } }
1348+
pub(crate) fn lifetime(did: DefId, name: Symbol) -> Self {
1349+
Self { name, did, kind: GenericParamDefKind::Lifetime { outlives: ThinVec::new() } }
13491350
}
13501351

13511352
pub(crate) fn is_synthetic_param(&self) -> bool {

src/librustdoc/html/format.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ impl clean::GenericParamDef {
188188
cx: &'a Context<'tcx>,
189189
) -> impl fmt::Display + 'a + Captures<'tcx> {
190190
display_fn(move |f| match &self.kind {
191-
clean::GenericParamDefKind::Lifetime { outlives } => {
191+
clean::GenericParamDefKind::Lifetime { outlives, .. } => {
192192
write!(f, "{}", self.name)?;
193193

194194
if !outlives.is_empty() {

src/librustdoc/json/conversions.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind {
456456
Lifetime { outlives } => GenericParamDefKind::Lifetime {
457457
outlives: outlives.into_iter().map(convert_lifetime).collect(),
458458
},
459-
Type { did: _, bounds, default, synthetic } => GenericParamDefKind::Type {
459+
Type { bounds, default, synthetic } => GenericParamDefKind::Type {
460460
bounds: bounds.into_tcx(tcx),
461461
default: default.map(|x| (*x).into_tcx(tcx)),
462462
synthetic,
@@ -486,19 +486,16 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
486486
outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(),
487487
}
488488
}
489-
clean::GenericParamDefKind::Type {
490-
did: _,
491-
bounds,
492-
default,
493-
synthetic,
494-
} => GenericParamDefKind::Type {
495-
bounds: bounds
496-
.into_iter()
497-
.map(|bound| bound.into_tcx(tcx))
498-
.collect(),
499-
default: default.map(|ty| (*ty).into_tcx(tcx)),
500-
synthetic,
501-
},
489+
clean::GenericParamDefKind::Type { bounds, default, synthetic } => {
490+
GenericParamDefKind::Type {
491+
bounds: bounds
492+
.into_iter()
493+
.map(|bound| bound.into_tcx(tcx))
494+
.collect(),
495+
default: default.map(|ty| (*ty).into_tcx(tcx)),
496+
synthetic,
497+
}
498+
}
502499
clean::GenericParamDefKind::Const {
503500
ty,
504501
default,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Here, `'a` and `'c` are late-bound and `'b`, `'d`, `T` and `N` are early-bound.
2+
3+
pub fn f<'a, 'b, 'c, 'd, T, const N: usize>()
4+
where
5+
'b:,
6+
'd:,
7+
{}
8+
9+
pub struct Ty;
10+
11+
impl Ty {
12+
pub fn f<'a, 'b, 'c, 'd, T, const N: usize>()
13+
where
14+
'b:,
15+
'd:,
16+
{}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Check that we correctly render late-bound lifetime params in source order
2+
// even if early-bound generic params are present.
3+
//
4+
// For context, at the time of writing early- and late-bound params are stored
5+
// separately in rustc and therefore rustdoc needs to manually merge them.
6+
7+
#![crate_name = "usr"]
8+
// aux-crate:dep=early-late-bound-lifetime-params.rs
9+
// edition:2021
10+
11+
// @has usr/fn.f.html
12+
// @has - '//pre[@class="rust item-decl"]' "fn f<'a, 'b, 'c, 'd, T, const N: usize>()"
13+
pub use dep::f;
14+
15+
// @has usr/struct.Ty.html
16+
// @has - '//*[@id="method.f"]' "fn f<'a, 'b, 'c, 'd, T, const N: usize>()"
17+
pub use dep::Ty;

0 commit comments

Comments
 (0)