Skip to content

Commit 5965af7

Browse files
committed
rustdoc: render late-bound lifetimes in generic parameter list of cross-crate functions and methods
1 parent 6330c27 commit 5965af7

File tree

4 files changed

+35
-8
lines changed

4 files changed

+35
-8
lines changed

src/librustdoc/clean/inline.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,22 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
243243
fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<clean::Function> {
244244
let sig = cx.tcx.fn_sig(did);
245245

246-
let predicates = cx.tcx.predicates_of(did);
246+
let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var {
247+
ty::BoundVariableKind::Region(ty::BrNamed(_, name)) if name != kw::UnderscoreLifetime => {
248+
Some(clean::GenericParamDef {
249+
name,
250+
kind: clean::GenericParamDefKind::Lifetime { outlives: Vec::new() },
251+
})
252+
}
253+
_ => None,
254+
});
255+
256+
let predicates = cx.tcx.explicit_predicates_of(did);
247257
let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
248258
// NOTE: generics need to be cleaned before the decl!
249-
let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
259+
let mut generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
260+
// FIXME: This does not place parameters in source order (late-bound ones come last)
261+
generics.params.extend(late_bound_regions);
250262
let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig);
251263
(generics, decl)
252264
});

src/librustdoc/clean/mod.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,12 +1144,28 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
11441144
}
11451145
}
11461146
ty::AssocKind::Fn => {
1147-
let generics = clean_ty_generics(
1147+
let sig = tcx.fn_sig(assoc_item.def_id);
1148+
1149+
let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var {
1150+
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
1151+
if name != kw::UnderscoreLifetime =>
1152+
{
1153+
Some(GenericParamDef {
1154+
name,
1155+
kind: GenericParamDefKind::Lifetime { outlives: Vec::new() },
1156+
})
1157+
}
1158+
_ => None,
1159+
});
1160+
1161+
let mut generics = clean_ty_generics(
11481162
cx,
11491163
tcx.generics_of(assoc_item.def_id),
11501164
tcx.explicit_predicates_of(assoc_item.def_id),
11511165
);
1152-
let sig = tcx.fn_sig(assoc_item.def_id);
1166+
// FIXME: This does not place parameters in source order (late-bound ones come last)
1167+
generics.params.extend(late_bound_regions);
1168+
11531169
let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig);
11541170

11551171
if assoc_item.fn_has_self_parameter {

src/librustdoc/clean/simplify.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,8 @@ pub(crate) fn merge_bounds(
9999
let last = trait_ref.trait_.segments.last_mut().expect("segments were empty");
100100

101101
trait_ref.generic_params.append(&mut bound_params);
102-
// Since the parameters (probably) originate from `tcx.collect_*_late_bound_regions` which
103-
// returns a hash set, sort them alphabetically to guarantee a stable and deterministic
104-
// output (and to fully deduplicate them).
102+
// Sort parameters (likely) originating from a hashset alphabetically to
103+
// produce predictable output (and to allow for full deduplication).
105104
trait_ref.generic_params.sort_unstable_by(|p, q| p.name.as_str().cmp(q.name.as_str()));
106105
trait_ref.generic_params.dedup_by_key(|p| p.name);
107106

src/test/rustdoc/issue-20727.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ pub mod reexport {
1919
// @has - '//*[@class="rust trait"]' 'trait Deref {'
2020
// @has - '//*[@class="rust trait"]' 'type Target: ?Sized;'
2121
// @has - '//*[@class="rust trait"]' \
22-
// "fn deref(&'a self) -> &'a Self::Target;"
22+
// "fn deref<'a>(&'a self) -> &'a Self::Target;"
2323
pub use issue_20727::Deref;
2424
}

0 commit comments

Comments
 (0)