Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1669,7 +1669,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let output = match coro {
Some(coro) => {
let fn_def_id = self.local_def_id(fn_node_id);
self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind)
}
None => match &decl.output {
FnRetTy::Ty(ty) => {
Expand Down Expand Up @@ -1754,9 +1754,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn_def_id: LocalDefId,
coro: CoroutineKind,
fn_kind: FnDeclKind,
fn_span: Span,
) -> hir::FnRetTy<'hir> {
let span = self.lower_span(fn_span);
let span = self.lower_span(output.span());

let (opaque_ty_node_id, allowed_features) = match coro {
CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1881,12 +1881,39 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let ty::Dynamic(_, _) = trait_pred.self_ty().skip_binder().kind() else {
return false;
};
if let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) =
self.tcx.hir_node_by_def_id(obligation.cause.body_id)
&& let hir::FnRetTy::Return(ty) = fn_sig.decl.output
&& let hir::TyKind::Path(qpath) = ty.kind
&& let hir::QPath::Resolved(None, path) = qpath
&& let Res::Def(DefKind::TyAlias, def_id) = path.res
{
// Do not suggest
// type T = dyn Trait;
// fn foo() -> impl T { .. }
err.span_note(self.tcx.def_span(def_id), "this type alias is unsized");
return false;
}

err.code(E0746);
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();
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/async-await/async-await-let-else.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely
--> $DIR/async-await-let-else.rs:47:13
|
LL | async fn foo2(x: Option<bool>) {
| ------------------------------ within this `impl Future<Output = ()>`
| - within this `impl Future<Output = ()>`
...
LL | is_send(foo2(Some(true)));
| ------- ^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/async-await/async-fn/dyn-in-return-type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//@ edition:2024

async fn f() -> dyn core::fmt::Debug {
//~^ ERROR return type cannot be a trait object without pointer indirection
//~| HELP consider returning an `impl Trait` instead of a `dyn Trait`
//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new`
loop {}
}

fn main() {}
22 changes: 22 additions & 0 deletions tests/ui/async-await/async-fn/dyn-in-return-type.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0746]: return type cannot be a trait object without pointer indirection
--> $DIR/dyn-in-return-type.rs:3:38
|
LL | async fn f() -> dyn core::fmt::Debug {
| ______________________________________^
... |
LL | | }
| |_^ doesn't have a size known at compile-time
|
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
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() -> Box<dyn core::fmt::Debug> {
| ++++ +

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0746`.
4 changes: 2 additions & 2 deletions tests/ui/async-await/async-fn/recurse-ice-129215.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ LL | a()
= help: the trait `Future` is not implemented for `()`

error[E0277]: `()` is not a future
--> $DIR/recurse-ice-129215.rs:3:1
--> $DIR/recurse-ice-129215.rs:3:13
|
LL | async fn a() {
| ^^^^^^^^^^^^ `()` is not a future
| ^ `()` is not a future
|
= help: the trait `Future` is not implemented for `()`

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0053]: method `foo` has an incompatible type for trait
--> $DIR/async-example-desugared-boxed-in-trait.rs:11:5
--> $DIR/async-example-desugared-boxed-in-trait.rs:11:28
|
LL | async fn foo(&self) -> i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future
| ^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future
|
note: type in trait
--> $DIR/async-example-desugared-boxed-in-trait.rs:7:22
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ warning: impl trait in impl method signature does not match trait method signatu
--> $DIR/async-example-desugared-boxed.rs:14:22
|
LL | async fn foo(&self) -> i32;
| --------------------------- return type from trait method defined here
| --- return type from trait method defined here
...
LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ warning: impl trait in impl method signature does not match trait method signatu
--> $DIR/async-example-desugared-manual.rs:22:22
|
LL | async fn foo(&self) -> i32;
| --------------------------- return type from trait method defined here
| --- return type from trait method defined here
...
LL | fn foo(&self) -> MyFuture {
| ^^^^^^^^
Expand Down
18 changes: 8 additions & 10 deletions tests/ui/async-await/in-trait/async-generics-and-bounds.stderr
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
error[E0311]: the parameter type `T` may not live long enough
--> $DIR/async-generics-and-bounds.rs:8:5
--> $DIR/async-generics-and-bounds.rs:8:28
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | the parameter type `T` must be valid for the anonymous lifetime as defined here...
| ...so that the reference type `&(T, U)` does not outlive the data it points at
| - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at
| |
| the parameter type `T` must be valid for the anonymous lifetime as defined here...
|
help: consider adding an explicit lifetime bound
|
LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, T: 'a;
| ++++ ++ ++ +++++++

error[E0311]: the parameter type `U` may not live long enough
--> $DIR/async-generics-and-bounds.rs:8:5
--> $DIR/async-generics-and-bounds.rs:8:28
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | the parameter type `U` must be valid for the anonymous lifetime as defined here...
| ...so that the reference type `&(T, U)` does not outlive the data it points at
| - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at
| |
| the parameter type `U` must be valid for the anonymous lifetime as defined here...
|
help: consider adding an explicit lifetime bound
|
Expand Down
18 changes: 8 additions & 10 deletions tests/ui/async-await/in-trait/async-generics.stderr
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
error[E0311]: the parameter type `T` may not live long enough
--> $DIR/async-generics.rs:5:5
--> $DIR/async-generics.rs:5:28
|
LL | async fn foo(&self) -> &(T, U);
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^
| | |
| | the parameter type `T` must be valid for the anonymous lifetime as defined here...
| ...so that the reference type `&(T, U)` does not outlive the data it points at
| - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at
| |
| the parameter type `T` must be valid for the anonymous lifetime as defined here...
|
help: consider adding an explicit lifetime bound
|
LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: 'a;
| ++++ ++ ++ +++++++++++

error[E0311]: the parameter type `U` may not live long enough
--> $DIR/async-generics.rs:5:5
--> $DIR/async-generics.rs:5:28
|
LL | async fn foo(&self) -> &(T, U);
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^
| | |
| | the parameter type `U` must be valid for the anonymous lifetime as defined here...
| ...so that the reference type `&(T, U)` does not outlive the data it points at
| - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at
| |
| the parameter type `U` must be valid for the anonymous lifetime as defined here...
|
help: consider adding an explicit lifetime bound
|
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
error[E0053]: method `foo` has an incompatible type for trait
--> $DIR/dont-project-to-specializable-projection.rs:14:5
--> $DIR/dont-project-to-specializable-projection.rs:14:35
|
LL | default async fn foo(_: T) -> &'static str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found future
| ^^^^^^^^^^^^ expected associated type, found future
|
note: type in trait
--> $DIR/dont-project-to-specializable-projection.rs:10:5
--> $DIR/dont-project-to-specializable-projection.rs:10:27
|
LL | async fn foo(_: T) -> &'static str;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^
= note: expected signature `fn(_) -> impl Future<Output = &'static str>`
found signature `fn(_) -> impl Future<Output = &'static str>`

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/async-await/inference_var_self_argument.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ LL | async fn foo(self: &dyn Foo) {
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)

error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/inference_var_self_argument.rs:5:5
--> $DIR/inference_var_self_argument.rs:5:33
|
LL | async fn foo(self: &dyn Foo) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
| ^ `Foo` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/async-await/issue-64130-3-other.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl Future<Output
--> $DIR/issue-64130-3-other.rs:25:12
|
LL | async fn bar() {
| -------------- within this `impl Future<Output = ()>`
| - within this `impl Future<Output = ()>`
...
LL | is_qux(bar());
| ^^^^^ unsatisfied trait bound
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/async-await/issues/issue-67893.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ LL | g(issue_67893::run())
| |
| required by a bound introduced by this call
|
::: $DIR/auxiliary/issue_67893.rs:9:1
::: $DIR/auxiliary/issue_67893.rs:9:19
|
LL | pub async fn run() {
| ------------------ within this `impl Future<Output = ()>`
| - within this `impl Future<Output = ()>`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `std::sync::MutexGuard<'_, ()>`
note: required because it's used within this `async` fn body
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/async-await/partial-drop-partial-reinit.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | gimme_send(foo());
| required by a bound introduced by this call
...
LL | async fn foo() {
| -------------- within this `impl Future<Output = ()>`
| - within this `impl Future<Output = ()>`
|
help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `NotSend`
--> $DIR/partial-drop-partial-reinit.rs:19:1
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/c-variadic/not-async.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that
--> $DIR/not-async.rs:5:62
|
LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {}
| ------------------------------------------------------------ ^^
| |
| opaque type defined here
| -^^
| |
| opaque type defined here
|
= note: hidden type `{async fn body of fn_cannot_be_async()}` captures lifetime `'_`

error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
--> $DIR/not-async.rs:12:70
|
LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {}
| ---------------------------------------------------------------- ^^
| |
| opaque type defined here
| -^^
| |
| opaque type defined here
|
= note: hidden type `{async fn body of S::method_cannot_be_async()}` captures lifetime `'_`

Expand Down
10 changes: 5 additions & 5 deletions tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0310]: the associated type `impl T` may not live long enough
--> $DIR/async-and-ret-ref.rs:7:5
--> $DIR/async-and-ret-ref.rs:7:23
|
LL | async fn foo() -> &'static impl T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| the associated type `impl T` must be valid for the static lifetime...
| ...so that the reference type `&'static impl T` does not outlive the data it points at
| ^^^^^^^^^^^^^^^
| |
| the associated type `impl T` must be valid for the static lifetime...
| ...so that the reference type `&'static impl T` does not outlive the data it points at

error: aborting due to 1 previous error

Expand Down
6 changes: 3 additions & 3 deletions tests/ui/inference/note-and-explain-ReVar-124973.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that
--> $DIR/note-and-explain-ReVar-124973.rs:5:73
|
LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {}
| ----------------------------------------------------------------------- ^^
| |
| opaque type defined here
| -^^
| |
| opaque type defined here
|
= note: hidden type `{async fn body of multiple_named_lifetimes<'a, 'b>()}` captures lifetime `'_`

Expand Down
18 changes: 6 additions & 12 deletions tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,18 @@ LL | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
= help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32`

error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32`
--> $DIR/issue-76168-hr-outlives-3.rs:6:1
--> $DIR/issue-76168-hr-outlives-3.rs:6:26
|
LL | / async fn wrapper<F>(f: F)
... |
LL | | F:,
LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
| |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
LL | async fn wrapper<F>(f: F)
| ^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
|
= help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32`

error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32`
--> $DIR/issue-76168-hr-outlives-3.rs:6:1
--> $DIR/issue-76168-hr-outlives-3.rs:6:26
|
LL | / async fn wrapper<F>(f: F)
... |
LL | | F:,
LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
| |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
LL | async fn wrapper<F>(f: F)
| ^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
|
= help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,12 @@ LL | #![feature(non_lifetime_binders)]
= note: `#[warn(incomplete_features)]` on by default

error[E0309]: the placeholder type `F` may not live long enough
--> $DIR/type-match-with-late-bound.rs:8:1
|
LL | async fn walk2<'a, T: 'a>(_: T)
| ^ -- the placeholder type `F` must be valid for the lifetime `'a` as defined here...
| _|
| |
LL | | where
LL | | for<F> F: 'a,
| |_________________^ ...so that the type `F` will meet its required lifetime bounds...
--> $DIR/type-match-with-late-bound.rs:8:32
|
LL | async fn walk2<'a, T: 'a>(_: T)
| -- ^ ...so that the type `F` will meet its required lifetime bounds...
| |
| the placeholder type `F` must be valid for the lifetime `'a` as defined here...
|
note: ...that is required by this bound
--> $DIR/type-match-with-late-bound.rs:10:15
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ LL | call(operation).await
| ^^^^^^^^^^^^^^^ expected `{async fn body of operation()}`, got `FutNothing<'_>`
|
note: previous use here
--> $DIR/hkl_forbidden4.rs:12:1
--> $DIR/hkl_forbidden4.rs:12:35
|
LL | async fn operation(_: &mut ()) -> () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^

error: aborting due to 2 previous errors

Loading
Loading