Account for async fn with dyn Trait return type in impl Trait suggestion

This commit is contained in:
Esteban Küber 2025-11-04 18:11:51 +00:00
parent 76f02cf142
commit 7868d20bd5
2 changed files with 20 additions and 9 deletions

View file

@ -1891,7 +1891,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
err.primary_message("return type cannot be a trait object without pointer indirection");
err.children.clear();
let span = obligation.cause.span;
let mut span = obligation.cause.span;
if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id)
&& let parent = self.tcx.parent(obligation.cause.body_id.into())
&& let DefKind::Fn = self.tcx.def_kind(parent)
&& self.tcx.asyncness(parent).is_async()
&& let Some(parent) = parent.as_local()
&& let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) =
self.tcx.hir_node_by_def_id(parent)
{
// Do not suggest (#147894)
// async fn foo() -> dyn Display impl { .. }
// and
// async fn foo() -> dyn Display Box<dyn { .. }>
span = fn_sig.decl.output.span();
}
let body = self.tcx.hir_body_owned_by(obligation.cause.body_id);
let mut visitor = ReturnsVisitor::default();

View file

@ -9,16 +9,13 @@ LL | | }
|
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
LL | async fn f() -> dyn core::fmt::Debug impl {
| ++++
LL - async fn f() -> dyn core::fmt::Debug {
LL + async fn f() -> impl core::fmt::Debug {
|
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
LL ~ async fn f() -> dyn core::fmt::Debug Box<dyn {
LL |
...
LL | loop {}
LL ~ }>
|
LL | async fn f() -> Box<dyn core::fmt::Debug> {
| ++++ +
error: aborting due to 1 previous error