Rollup merge of #103892 - compiler-errors:afit-rustdoc, r=GuillaumeGomez
Properly render asyncness for trait fns without default body We weren't properly desugaring async fns in traits unless they had default bodies (in which case rustdoc treats them much like they came from an impl). cc ```@yoshuawuyts``` should help with https://rust-lang.zulipchat.com/#narrow/stream/330606-wg-async.2Fasync-fn-in-trait-impl/topic/type.20inside.20.60async.20fn.60.20body.20must.20be.20known.20in.20this.20context/near/306894869
This commit is contained in:
commit
6e582cadc3
@ -413,7 +413,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Ty<'_>> {
|
||||
/// Check if a function is async.
|
||||
fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
|
||||
let node = tcx.hir().get_by_def_id(def_id.expect_local());
|
||||
if let Some(fn_kind) = node.fn_kind() { fn_kind.asyncness() } else { hir::IsAsync::NotAsync }
|
||||
node.fn_sig().map_or(hir::IsAsync::NotAsync, |sig| sig.header.asyncness)
|
||||
}
|
||||
|
||||
/// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead.
|
||||
|
@ -880,7 +880,7 @@ fn clean_fn_or_proc_macro<'tcx>(
|
||||
ProcMacroItem(ProcMacro { kind, helpers })
|
||||
}
|
||||
None => {
|
||||
let mut func = clean_function(cx, sig, generics, body_id);
|
||||
let mut func = clean_function(cx, sig, generics, FunctionArgs::Body(body_id));
|
||||
clean_fn_decl_legacy_const_generics(&mut func, attrs);
|
||||
FunctionItem(func)
|
||||
}
|
||||
@ -917,16 +917,28 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib
|
||||
}
|
||||
}
|
||||
|
||||
enum FunctionArgs<'tcx> {
|
||||
Body(hir::BodyId),
|
||||
Names(&'tcx [Ident]),
|
||||
}
|
||||
|
||||
fn clean_function<'tcx>(
|
||||
cx: &mut DocContext<'tcx>,
|
||||
sig: &hir::FnSig<'tcx>,
|
||||
generics: &hir::Generics<'tcx>,
|
||||
body_id: hir::BodyId,
|
||||
args: FunctionArgs<'tcx>,
|
||||
) -> Box<Function> {
|
||||
let (generics, decl) = enter_impl_trait(cx, |cx| {
|
||||
// NOTE: generics must be cleaned before args
|
||||
let generics = clean_generics(generics, cx);
|
||||
let args = clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id);
|
||||
let args = match args {
|
||||
FunctionArgs::Body(body_id) => {
|
||||
clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id)
|
||||
}
|
||||
FunctionArgs::Names(names) => {
|
||||
clean_args_from_types_and_names(cx, sig.decl.inputs, names)
|
||||
}
|
||||
};
|
||||
let mut decl = clean_fn_decl_with_args(cx, sig.decl, args);
|
||||
if sig.header.is_async() {
|
||||
decl.output = decl.sugared_async_return_type();
|
||||
@ -1051,18 +1063,12 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
|
||||
),
|
||||
hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(clean_ty(ty, cx)),
|
||||
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
|
||||
let m = clean_function(cx, sig, trait_item.generics, body);
|
||||
let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body));
|
||||
MethodItem(m, None)
|
||||
}
|
||||
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => {
|
||||
let (generics, decl) = enter_impl_trait(cx, |cx| {
|
||||
// NOTE: generics must be cleaned before args
|
||||
let generics = clean_generics(trait_item.generics, cx);
|
||||
let args = clean_args_from_types_and_names(cx, sig.decl.inputs, names);
|
||||
let decl = clean_fn_decl_with_args(cx, sig.decl, args);
|
||||
(generics, decl)
|
||||
});
|
||||
TyMethodItem(Box::new(Function { decl, generics }))
|
||||
let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Names(names));
|
||||
TyMethodItem(m)
|
||||
}
|
||||
hir::TraitItemKind::Type(bounds, Some(default)) => {
|
||||
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
|
||||
@ -1099,7 +1105,7 @@ pub(crate) fn clean_impl_item<'tcx>(
|
||||
AssocConstItem(clean_ty(ty, cx), default)
|
||||
}
|
||||
hir::ImplItemKind::Fn(ref sig, body) => {
|
||||
let m = clean_function(cx, sig, impl_.generics, body);
|
||||
let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body));
|
||||
let defaultness = cx.tcx.impl_defaultness(impl_.owner_id);
|
||||
MethodItem(m, Some(defaultness))
|
||||
}
|
||||
|
@ -694,13 +694,10 @@ impl Item {
|
||||
asyncness: hir::IsAsync::NotAsync,
|
||||
}
|
||||
}
|
||||
ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) => {
|
||||
ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) | ItemKind::TyMethodItem(_) => {
|
||||
let def_id = self.item_id.as_def_id().unwrap();
|
||||
build_fn_header(def_id, tcx, tcx.asyncness(def_id))
|
||||
}
|
||||
ItemKind::TyMethodItem(_) => {
|
||||
build_fn_header(self.item_id.as_def_id().unwrap(), tcx, hir::IsAsync::NotAsync)
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
Some(header)
|
||||
|
14
src/test/rustdoc/async-trait-sig.rs
Normal file
14
src/test/rustdoc/async-trait-sig.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// edition:2021
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub trait Foo {
|
||||
// @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn bar() -> i32"
|
||||
async fn bar() -> i32;
|
||||
|
||||
// @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn baz() -> i32"
|
||||
async fn baz() -> i32 {
|
||||
1
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user