Skip to content

Commit

Permalink
Auto merge of rust-lang#121022 - fmease:rustdoc-x-crate-late-bound-lt…
Browse files Browse the repository at this point in the history
…-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
  • Loading branch information
bors committed Feb 13, 2024
2 parents fd9bb7f + c19c531 commit 7d7a418
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/librustdoc/clean/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ where
match br {
// We only care about named late bound regions, as we need to add them
// to the 'for<>' section
ty::BrNamed(_, name) => Some(GenericParamDef::lifetime(name)),
ty::BrNamed(did, name) => Some(GenericParamDef::lifetime(did, name)),
_ => None,
}
})
Expand Down
6 changes: 5 additions & 1 deletion src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,12 @@ fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<c
let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
// NOTE: generics need to be cleaned before the decl!
let mut generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
// FIXME: This does not place parameters in source order (late-bound ones come last)
generics.params.extend(clean_bound_vars(sig.bound_vars()));
// FIXME(fmease): Does this work in the presence of synthetic params (impl-Trait, host effect)?
// FIXME(fmease): Optimization: Don't call def_ident_span on non-lifetime params!
if !sig.bound_vars().is_empty() {
generics.params.sort_by_key(|param| cx.tcx.def_ident_span(param.did).unwrap());
}
let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig);
(generics, decl)
});
Expand Down
33 changes: 19 additions & 14 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,6 @@ fn clean_generic_param_def<'tcx>(
(
def.name,
GenericParamDefKind::Type {
did: def.def_id,
bounds: ThinVec::new(), // These are filled in from the where-clauses.
default: default.map(Box::new),
synthetic,
Expand Down Expand Up @@ -557,7 +556,7 @@ fn clean_generic_param_def<'tcx>(
),
};

GenericParamDef { name, kind }
GenericParamDef { name, did: def.def_id, kind }
}

fn clean_generic_param<'tcx>(
Expand Down Expand Up @@ -596,7 +595,6 @@ fn clean_generic_param<'tcx>(
(
param.name.ident().name,
GenericParamDefKind::Type {
did: param.def_id.to_def_id(),
bounds,
default: default.map(|t| clean_ty(t, cx)).map(Box::new),
synthetic,
Expand All @@ -614,7 +612,7 @@ fn clean_generic_param<'tcx>(
),
};

GenericParamDef { name, kind }
GenericParamDef { name, did: param.def_id.to_def_id(), kind }
}

/// Synthetic type-parameters are inserted after normal ones.
Expand Down Expand Up @@ -646,8 +644,8 @@ pub(crate) fn clean_generics<'tcx>(
let param = clean_generic_param(cx, Some(gens), param);
match param.kind {
GenericParamDefKind::Lifetime { .. } => unreachable!(),
GenericParamDefKind::Type { did, ref bounds, .. } => {
cx.impl_trait_bounds.insert(did.into(), bounds.to_vec());
GenericParamDefKind::Type { ref bounds, .. } => {
cx.impl_trait_bounds.insert(param.did.into(), bounds.to_vec());
}
GenericParamDefKind::Const { .. } => unreachable!(),
}
Expand Down Expand Up @@ -1064,8 +1062,11 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib
match literal.kind {
ast::LitKind::Int(a, _) => {
let gen = func.generics.params.remove(0);
if let GenericParamDef { name, kind: GenericParamDefKind::Const { ty, .. } } =
gen
if let GenericParamDef {
name,
kind: GenericParamDefKind::Const { ty, .. },
..
} = gen
{
func.decl
.inputs
Expand Down Expand Up @@ -1365,8 +1366,12 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
tcx.generics_of(assoc_item.def_id),
tcx.explicit_predicates_of(assoc_item.def_id),
);
// FIXME: This does not place parameters in source order (late-bound ones come last)
generics.params.extend(clean_bound_vars(sig.bound_vars()));
// FIXME(fmease): Does this work in the presence of synthetic params (impl-Trait, host effect)?
// FIXME(fmease): Optimization: Don't call def_ident_span on non-lifetime params!
if !sig.bound_vars().is_empty() {
generics.params.sort_by_key(|param| tcx.def_ident_span(param.did).unwrap());
}

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

Expand Down Expand Up @@ -2192,10 +2197,10 @@ pub(crate) fn clean_middle_ty<'tcx>(
.iter()
.flat_map(|pred| pred.bound_vars())
.filter_map(|var| match var {
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
ty::BoundVariableKind::Region(ty::BrNamed(did, name))
if name != kw::UnderscoreLifetime =>
{
Some(GenericParamDef::lifetime(name))
Some(GenericParamDef::lifetime(did, name))
}
_ => None,
})
Expand Down Expand Up @@ -3167,15 +3172,15 @@ fn clean_bound_vars<'tcx>(
bound_vars
.into_iter()
.filter_map(|var| match var {
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
ty::BoundVariableKind::Region(ty::BrNamed(did, name))
if name != kw::UnderscoreLifetime =>
{
Some(GenericParamDef::lifetime(name))
Some(GenericParamDef::lifetime(did, name))
}
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(did, name)) => Some(GenericParamDef {
name,
did,
kind: GenericParamDefKind::Type {
did,
bounds: ThinVec::new(),
default: None,
synthetic: false,
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/clean/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ pub(crate) fn move_bounds_to_generic_parameters(generics: &mut clean::Generics)
} else if let WherePredicate::RegionPredicate { lifetime: Lifetime(arg), bounds } =
&mut pred
&& let Some(GenericParamDef {
kind: GenericParamDefKind::Lifetime { outlives: param_bounds },
kind: GenericParamDefKind::Lifetime { outlives: param_bounds, .. },
..
}) = generics.params.iter_mut().find(|param| &param.name == arg)
{
Expand Down
7 changes: 4 additions & 3 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1326,7 +1326,7 @@ impl WherePredicate {
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub(crate) enum GenericParamDefKind {
Lifetime { outlives: ThinVec<Lifetime> },
Type { did: DefId, bounds: ThinVec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
Type { bounds: ThinVec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
// Option<Box<String>> makes this type smaller than `Option<String>` would.
Const { ty: Box<Type>, default: Option<Box<String>>, is_host_effect: bool },
}
Expand All @@ -1339,13 +1339,14 @@ impl GenericParamDefKind {

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub(crate) struct GenericParamDef {
pub(crate) did: DefId,
pub(crate) name: Symbol,
pub(crate) kind: GenericParamDefKind,
}

impl GenericParamDef {
pub(crate) fn lifetime(name: Symbol) -> Self {
Self { name, kind: GenericParamDefKind::Lifetime { outlives: ThinVec::new() } }
pub(crate) fn lifetime(did: DefId, name: Symbol) -> Self {
Self { name, did, kind: GenericParamDefKind::Lifetime { outlives: ThinVec::new() } }
}

pub(crate) fn is_synthetic_param(&self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl clean::GenericParamDef {
cx: &'a Context<'tcx>,
) -> impl fmt::Display + 'a + Captures<'tcx> {
display_fn(move |f| match &self.kind {
clean::GenericParamDefKind::Lifetime { outlives } => {
clean::GenericParamDefKind::Lifetime { outlives, .. } => {
write!(f, "{}", self.name)?;

if !outlives.is_empty() {
Expand Down
25 changes: 11 additions & 14 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind {
Lifetime { outlives } => GenericParamDefKind::Lifetime {
outlives: outlives.into_iter().map(convert_lifetime).collect(),
},
Type { did: _, bounds, default, synthetic } => GenericParamDefKind::Type {
Type { bounds, default, synthetic } => GenericParamDefKind::Type {
bounds: bounds.into_tcx(tcx),
default: default.map(|x| (*x).into_tcx(tcx)),
synthetic,
Expand Down Expand Up @@ -486,19 +486,16 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(),
}
}
clean::GenericParamDefKind::Type {
did: _,
bounds,
default,
synthetic,
} => GenericParamDefKind::Type {
bounds: bounds
.into_iter()
.map(|bound| bound.into_tcx(tcx))
.collect(),
default: default.map(|ty| (*ty).into_tcx(tcx)),
synthetic,
},
clean::GenericParamDefKind::Type { bounds, default, synthetic } => {
GenericParamDefKind::Type {
bounds: bounds
.into_iter()
.map(|bound| bound.into_tcx(tcx))
.collect(),
default: default.map(|ty| (*ty).into_tcx(tcx)),
synthetic,
}
}
clean::GenericParamDefKind::Const {
ty,
default,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Here, `'a` and `'c` are late-bound and `'b`, `'d`, `T` and `N` are early-bound.

pub fn f<'a, 'b, 'c, 'd, T, const N: usize>()
where
'b:,
'd:,
{}

pub struct Ty;

impl Ty {
pub fn f<'a, 'b, 'c, 'd, T, const N: usize>()
where
'b:,
'd:,
{}
}
17 changes: 17 additions & 0 deletions tests/rustdoc/inline_cross/early-late-bound-lifetime-params.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Check that we correctly render late-bound lifetime params in source order
// even if early-bound generic params are present.
//
// For context, at the time of writing early- and late-bound params are stored
// separately in rustc and therefore rustdoc needs to manually merge them.

#![crate_name = "usr"]
// aux-crate:dep=early-late-bound-lifetime-params.rs
// edition:2021

// @has usr/fn.f.html
// @has - '//pre[@class="rust item-decl"]' "fn f<'a, 'b, 'c, 'd, T, const N: usize>()"
pub use dep::f;

// @has usr/struct.Ty.html
// @has - '//*[@id="method.f"]' "fn f<'a, 'b, 'c, 'd, T, const N: usize>()"
pub use dep::Ty;

0 comments on commit 7d7a418

Please sign in to comment.