Skip to content

Commit 04da15e

Browse files
committed
rustdoc: fix delegated impl signatures
1 parent 99eed20 commit 04da15e

4 files changed

Lines changed: 92 additions & 13 deletions

File tree

src/librustdoc/clean/mod.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,13 @@ fn clean_fn_or_proc_macro<'tcx>(
10891089
match macro_kind {
10901090
Some(kind) => clean_proc_macro(item, name, kind, cx.tcx),
10911091
None => {
1092-
let mut func = clean_function(cx, sig, generics, ParamsSrc::Body(body_id));
1092+
let mut func = clean_function(
1093+
cx,
1094+
item.owner_id.to_def_id(),
1095+
sig,
1096+
generics,
1097+
ParamsSrc::Body(body_id),
1098+
);
10931099
clean_fn_decl_legacy_const_generics(&mut func, attrs);
10941100
FunctionItem(func)
10951101
}
@@ -1124,10 +1130,15 @@ enum ParamsSrc<'tcx> {
11241130

11251131
fn clean_function<'tcx>(
11261132
cx: &mut DocContext<'tcx>,
1133+
def_id: DefId,
11271134
sig: &hir::FnSig<'tcx>,
11281135
generics: &hir::Generics<'tcx>,
11291136
params: ParamsSrc<'tcx>,
11301137
) -> Box<Function> {
1138+
if sig.decl.opt_delegation_sig_id().is_some() {
1139+
return enter_impl_trait(cx, |cx| inline::build_function(cx, def_id));
1140+
}
1141+
11311142
let (generics, decl) = enter_impl_trait(cx, |cx| {
11321143
// NOTE: Generics must be cleaned before params.
11331144
let generics = clean_generics(generics, cx);
@@ -1270,11 +1281,18 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
12701281
RequiredAssocConstItem(generics, Box::new(clean_ty(ty, cx)))
12711282
}
12721283
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
1273-
let m = clean_function(cx, sig, trait_item.generics, ParamsSrc::Body(body));
1284+
let m =
1285+
clean_function(cx, local_did, sig, trait_item.generics, ParamsSrc::Body(body));
12741286
MethodItem(m, Defaultness::from_trait_item(trait_item.defaultness))
12751287
}
12761288
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(idents)) => {
1277-
let m = clean_function(cx, sig, trait_item.generics, ParamsSrc::Idents(idents));
1289+
let m = clean_function(
1290+
cx,
1291+
local_did,
1292+
sig,
1293+
trait_item.generics,
1294+
ParamsSrc::Idents(idents),
1295+
);
12781296
RequiredMethodItem(m, Defaultness::from_trait_item(trait_item.defaultness))
12791297
}
12801298
hir::TraitItemKind::Type(bounds, Some(default)) => {
@@ -1315,7 +1333,7 @@ pub(crate) fn clean_impl_item<'tcx>(
13151333
type_: clean_ty(ty, cx),
13161334
})),
13171335
hir::ImplItemKind::Fn(ref sig, body) => {
1318-
let m = clean_function(cx, sig, impl_.generics, ParamsSrc::Body(body));
1336+
let m = clean_function(cx, local_did, sig, impl_.generics, ParamsSrc::Body(body));
13191337
let defaultness = match impl_.impl_kind {
13201338
hir::ImplItemImplKind::Inherent { .. } => hir::Defaultness::Final,
13211339
hir::ImplItemImplKind::Trait { defaultness, .. } => defaultness,
@@ -3259,7 +3277,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
32593277
cx.with_param_env(def_id, |cx| {
32603278
let kind = match item.kind {
32613279
hir::ForeignItemKind::Fn(sig, idents, generics) => ForeignFunctionItem(
3262-
clean_function(cx, &sig, generics, ParamsSrc::Idents(idents)),
3280+
clean_function(cx, def_id, &sig, generics, ParamsSrc::Idents(idents)),
32633281
sig.header.safety(),
32643282
),
32653283
hir::ForeignItemKind::Static(ty, mutability, safety) => ForeignStaticItem(

src/librustdoc/clean/simplify.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,25 @@ pub(crate) fn sized_bounds(cx: &mut DocContext<'_>, generics: &mut clean::Generi
136136
// Note that associated types also have an implicit `Sized` bound but we
137137
// don't actually know the set of associated types right here so that
138138
// should be handled when cleaning associated types.
139-
generics.where_predicates.retain(|pred| {
140-
let WP::BoundPredicate { ty: clean::Generic(param), bounds, .. } = pred else {
139+
generics.where_predicates.retain_mut(|pred| {
140+
let WP::BoundPredicate { ty, bounds, .. } = pred else {
141141
return true;
142142
};
143143

144+
// FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized`
145+
// is shown and none of the new sizedness traits leak into documentation.
146+
bounds.retain(|b| !b.is_meta_sized_bound(cx.tcx));
147+
148+
let clean::Generic(param) = ty else {
149+
return !bounds.is_empty();
150+
};
151+
144152
if bounds.iter().any(|b| b.is_sized_bound(cx.tcx)) {
145153
sized_params.insert(*param);
146-
false
147-
} else if bounds.iter().any(|b| b.is_meta_sized_bound(cx.tcx)) {
148-
// FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized`
149-
// is shown and none of the new sizedness traits leak into documentation.
150-
false
154+
bounds.retain(|b| !b.is_sized_bound(cx.tcx));
155+
!bounds.is_empty()
151156
} else {
152-
true
157+
!bounds.is_empty()
153158
}
154159
});
155160

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![feature(fn_delegation)]
2+
#![allow(incomplete_features)]
3+
4+
pub fn external(_: impl FnOnce()) {}
5+
6+
fn delegated_to(_: impl FnOnce()) {}
7+
8+
pub reuse delegated_to as delegated;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/155728>
2+
// Make sure delegating functions with `impl Trait` in argument position works correctly.
3+
//@ aux-crate:fn_delegation_impl_trait_aux=fn-delegation-impl-trait-aux.rs
4+
#![feature(fn_delegation)]
5+
#![allow(incomplete_features)]
6+
7+
extern crate fn_delegation_impl_trait_aux as aux;
8+
9+
fn foo(_: impl FnOnce()) {}
10+
11+
//@ has fn_delegation_impl_trait/fn.top_level.html '//pre[@class="rust item-decl"]' 'pub fn top_level(arg0: impl FnOnce())'
12+
pub reuse foo as top_level;
13+
14+
pub struct S;
15+
16+
//@ has fn_delegation_impl_trait/struct.S.html '//*[@id="method.method"]' 'pub fn method(arg0: impl FnOnce())'
17+
impl S {
18+
pub reuse foo as method;
19+
}
20+
21+
pub trait A {
22+
fn f(&self, _: impl FnOnce()) {}
23+
}
24+
25+
impl A for S {}
26+
27+
//@ has fn_delegation_impl_trait/struct.S.html '//*[@id="method.f"]' 'pub fn f(self: &S, arg1: impl FnOnce())'
28+
//@ !has fn_delegation_impl_trait/struct.S.html '//*[@id="method.f"]' 'MetaSized'
29+
impl S {
30+
pub reuse <S as A>::f;
31+
}
32+
33+
//@ has fn_delegation_impl_trait/trait.T.html '//*[@id="method.provided"]' 'fn provided(arg0: impl FnOnce())'
34+
pub trait T {
35+
reuse foo as provided;
36+
}
37+
38+
//@ has fn_delegation_impl_trait/fn.cross_crate.html '//pre[@class="rust item-decl"]' 'pub fn cross_crate(arg0: impl FnOnce())'
39+
pub reuse aux::external as cross_crate;
40+
41+
//@ has fn_delegation_impl_trait/fn.inlined_cross_crate_delegated.html '//pre[@class="rust item-decl"]' 'pub fn inlined_cross_crate_delegated(arg0: impl FnOnce())'
42+
#[doc(inline)]
43+
pub use aux::delegated as inlined_cross_crate_delegated;
44+
45+
//@ has fn_delegation_impl_trait/fn.redelegated_cross_crate.html '//pre[@class="rust item-decl"]' 'pub fn redelegated_cross_crate(arg0: impl FnOnce())'
46+
pub reuse aux::delegated as redelegated_cross_crate;
47+
48+
pub fn main() {}

0 commit comments

Comments
 (0)