From 5965af701090591edad308e9877d72bbe2221b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 2 Nov 2022 15:10:36 +0100 Subject: [PATCH] rustdoc: render late-bound lifetimes in generic parameter list of cross-crate functions and methods --- src/librustdoc/clean/inline.rs | 16 ++++++++++++++-- src/librustdoc/clean/mod.rs | 20 ++++++++++++++++++-- src/librustdoc/clean/simplify.rs | 5 ++--- src/test/rustdoc/issue-20727.rs | 2 +- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 841c4f9d530..bfbe143c202 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -243,10 +243,22 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box { let sig = cx.tcx.fn_sig(did); - let predicates = cx.tcx.predicates_of(did); + let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var { + ty::BoundVariableKind::Region(ty::BrNamed(_, name)) if name != kw::UnderscoreLifetime => { + Some(clean::GenericParamDef { + name, + kind: clean::GenericParamDefKind::Lifetime { outlives: Vec::new() }, + }) + } + _ => None, + }); + + let predicates = cx.tcx.explicit_predicates_of(did); let (generics, decl) = clean::enter_impl_trait(cx, |cx| { // NOTE: generics need to be cleaned before the decl! - let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); + 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(late_bound_regions); let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig); (generics, decl) }); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8d38f2df0d8..a179bd3c39f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1144,12 +1144,28 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } } ty::AssocKind::Fn => { - let generics = clean_ty_generics( + let sig = tcx.fn_sig(assoc_item.def_id); + + let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var { + ty::BoundVariableKind::Region(ty::BrNamed(_, name)) + if name != kw::UnderscoreLifetime => + { + Some(GenericParamDef { + name, + kind: GenericParamDefKind::Lifetime { outlives: Vec::new() }, + }) + } + _ => None, + }); + + let mut generics = clean_ty_generics( cx, tcx.generics_of(assoc_item.def_id), tcx.explicit_predicates_of(assoc_item.def_id), ); - let sig = tcx.fn_sig(assoc_item.def_id); + // FIXME: This does not place parameters in source order (late-bound ones come last) + generics.params.extend(late_bound_regions); + let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig); if assoc_item.fn_has_self_parameter { diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 1c184f9b269..cd9dab1b1d5 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -99,9 +99,8 @@ pub(crate) fn merge_bounds( let last = trait_ref.trait_.segments.last_mut().expect("segments were empty"); trait_ref.generic_params.append(&mut bound_params); - // Since the parameters (probably) originate from `tcx.collect_*_late_bound_regions` which - // returns a hash set, sort them alphabetically to guarantee a stable and deterministic - // output (and to fully deduplicate them). + // Sort parameters (likely) originating from a hashset alphabetically to + // produce predictable output (and to allow for full deduplication). trait_ref.generic_params.sort_unstable_by(|p, q| p.name.as_str().cmp(q.name.as_str())); trait_ref.generic_params.dedup_by_key(|p| p.name); diff --git a/src/test/rustdoc/issue-20727.rs b/src/test/rustdoc/issue-20727.rs index f7acffcb4e5..c1a98cd57da 100644 --- a/src/test/rustdoc/issue-20727.rs +++ b/src/test/rustdoc/issue-20727.rs @@ -19,6 +19,6 @@ pub mod reexport { // @has - '//*[@class="rust trait"]' 'trait Deref {' // @has - '//*[@class="rust trait"]' 'type Target: ?Sized;' // @has - '//*[@class="rust trait"]' \ - // "fn deref(&'a self) -> &'a Self::Target;" + // "fn deref<'a>(&'a self) -> &'a Self::Target;" pub use issue_20727::Deref; }