diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index dd458ab1ea70f..c491e5c52a09c 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -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) => { @@ -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), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index cd0dbb4d87f99..b0e8364aeef1f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1881,12 +1881,56 @@ 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, .. }, .. }) + | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. }) + | Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(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"); + err.multipart_suggestion( + format!( + "consider boxing the return type, and wrapping all of the returned values in \ + `Box::new`", + ), + vec![ + (ty.span.shrink_to_lo(), "Box<".to_string()), + (ty.span.shrink_to_hi(), ">".to_string()), + ], + Applicability::MaybeIncorrect, + ); + 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 | DefKind::AssocFn = 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, .. }, .. }) + | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. }) + | Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(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 + span = fn_sig.decl.output.span(); + err.span(span); + } let body = self.tcx.hir_body_owned_by(obligation.cause.body_id); let mut visitor = ReturnsVisitor::default(); diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr index e366dc2d21958..8b8af1ebaed39 100644 --- a/src/tools/clippy/tests/ui/future_not_send.stderr +++ b/src/tools/clippy/tests/ui/future_not_send.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:8:1 + --> tests/ui/future_not_send.rs:8:62 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` + | ^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:11:20 @@ -23,10 +23,10 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:14:1 + --> tests/ui/future_not_send.rs:14:41 | LL | pub async fn public_future(rc: Rc<[u8]>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` + | ^ future returned by `public_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:17:20 @@ -39,10 +39,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:24:1 + --> tests/ui/future_not_send.rs:24:63 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future2` is not `Send` + | ^^^^ future returned by `private_future2` is not `Send` | note: captured value is not `Send` --> tests/ui/future_not_send.rs:24:26 @@ -58,10 +58,10 @@ LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { = note: `std::cell::Cell` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:30:1 + --> tests/ui/future_not_send.rs:30:42 | LL | pub async fn public_future2(rc: Rc<[u8]>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future2` is not `Send` + | ^ future returned by `public_future2` is not `Send` | note: captured value is not `Send` --> tests/ui/future_not_send.rs:30:29 @@ -71,10 +71,10 @@ LL | pub async fn public_future2(rc: Rc<[u8]>) {} = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:42:5 + --> tests/ui/future_not_send.rs:42:39 | LL | async fn private_future(&self) -> usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` + | ^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:45:24 @@ -87,10 +87,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:49:5 + --> tests/ui/future_not_send.rs:49:38 | LL | pub async fn public_future(&self) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` + | ^ future returned by `public_future` is not `Send` | note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` --> tests/ui/future_not_send.rs:49:32 @@ -100,13 +100,10 @@ LL | pub async fn public_future(&self) { = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:61:1 + --> tests/ui/future_not_send.rs:61:37 | -LL | / async fn generic_future(t: T) -> T -LL | | -LL | | where -LL | | T: Send, - | |____________^ future returned by `generic_future` is not `Send` +LL | async fn generic_future(t: T) -> T + | ^ future returned by `generic_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:67:20 @@ -118,10 +115,10 @@ LL | async { true }.await; = note: `T` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:83:1 + --> tests/ui/future_not_send.rs:83:51 | LL | async fn generic_future_always_unsend(_: Rc) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `generic_future_always_unsend` is not `Send` + | ^ future returned by `generic_future_always_unsend` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:86:20 diff --git a/tests/ui/async-await/async-await-let-else.stderr b/tests/ui/async-await/async-await-let-else.stderr index 5883f34f87de6..b5b56d3242f4d 100644 --- a/tests/ui/async-await/async-await-let-else.stderr +++ b/tests/ui/async-await/async-await-let-else.stderr @@ -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) { - | ------------------------------ within this `impl Future` + | - within this `impl Future` ... LL | is_send(foo2(Some(true))); | ------- ^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.fixed b/tests/ui/async-await/async-fn/dyn-in-return-type.fixed new file mode 100644 index 0000000000000..6a717f628460e --- /dev/null +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.fixed @@ -0,0 +1,30 @@ +//@ edition:2024 +//@ run-rustfix + +async fn f() -> Box { +//~^ 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` + Box::new("") +} +trait T { + async fn f(&self) -> Box { + //~^ 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` + Box::new("") + } +} +impl T for () { + async fn f(&self) -> Box { + //~^ 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` + Box::new("") + } +} + +fn main() { + let _ = f(); + let _ = ().f(); +} diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.rs b/tests/ui/async-await/async-fn/dyn-in-return-type.rs new file mode 100644 index 0000000000000..47d5e371f55f6 --- /dev/null +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.rs @@ -0,0 +1,30 @@ +//@ edition:2024 +//@ run-rustfix + +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` + Box::new("") +} +trait T { + async fn f(&self) -> 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` + Box::new("") + } +} +impl T for () { + async fn f(&self) -> 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` + Box::new("") + } +} + +fn main() { + let _ = f(); + let _ = ().f(); +} diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr new file mode 100644 index 0000000000000..0d8a92d33cf9a --- /dev/null +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr @@ -0,0 +1,51 @@ +error[E0746]: return type cannot be a trait object without pointer indirection + --> $DIR/dyn-in-return-type.rs:4:17 + | +LL | async fn f() -> dyn core::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ + | +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 { + | ++++ + + +error[E0746]: return type cannot be a trait object without pointer indirection + --> $DIR/dyn-in-return-type.rs:11:26 + | +LL | async fn f(&self) -> dyn core::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ + | +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL - async fn f(&self) -> dyn core::fmt::Debug { +LL + async fn f(&self) -> impl core::fmt::Debug { + | +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` + | +LL | async fn f(&self) -> Box { + | ++++ + + +error[E0746]: return type cannot be a trait object without pointer indirection + --> $DIR/dyn-in-return-type.rs:19:26 + | +LL | async fn f(&self) -> dyn core::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ + | +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL - async fn f(&self) -> dyn core::fmt::Debug { +LL + async fn f(&self) -> impl core::fmt::Debug { + | +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` + | +LL | async fn f(&self) -> Box { + | ++++ + + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0746`. diff --git a/tests/ui/async-await/async-fn/recurse-ice-129215.stderr b/tests/ui/async-await/async-fn/recurse-ice-129215.stderr index 98c7be2a5a3f2..232246590cf10 100644 --- a/tests/ui/async-await/async-fn/recurse-ice-129215.stderr +++ b/tests/ui/async-await/async-fn/recurse-ice-129215.stderr @@ -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 `()` diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr index 54df0edf5a8e4..c98df134072eb 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr @@ -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>>`, found future + | ^^^ expected `Pin>>`, found future | note: type in trait --> $DIR/async-example-desugared-boxed-in-trait.rs:7:22 diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr index b7f2879727f24..d3765a7e6e6fd 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr @@ -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 + '_>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr index 86546df88c175..3328dea37fe4d 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr @@ -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 { | ^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr index 183b0fa152aa3..52fd887b296f4 100644 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr +++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr @@ -1,11 +1,10 @@ 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 | @@ -13,13 +12,12 @@ LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Has | ++++ ++ ++ +++++++ 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 | diff --git a/tests/ui/async-await/in-trait/async-generics.stderr b/tests/ui/async-await/in-trait/async-generics.stderr index 8916ef5ab6830..3f44e4cdb6778 100644 --- a/tests/ui/async-await/in-trait/async-generics.stderr +++ b/tests/ui/async-await/in-trait/async-generics.stderr @@ -1,11 +1,10 @@ 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 | @@ -13,13 +12,12 @@ 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 | diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr index 823d8d5b92fce..d0c11565f4e90 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr @@ -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` found signature `fn(_) -> impl Future` diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr index 1fccc32470ff6..c4240a095e685 100644 --- a/tests/ui/async-await/inference_var_self_argument.stderr +++ b/tests/ui/async-await/inference_var_self_argument.stderr @@ -8,10 +8,10 @@ LL | async fn foo(self: &dyn Foo) { = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (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 diff --git a/tests/ui/async-await/issue-64130-3-other.stderr b/tests/ui/async-await/issue-64130-3-other.stderr index d683366ed4737..531a7028f7e0e 100644 --- a/tests/ui/async-await/issue-64130-3-other.stderr +++ b/tests/ui/async-await/issue-64130-3-other.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl Future $DIR/issue-64130-3-other.rs:25:12 | LL | async fn bar() { - | -------------- within this `impl Future` + | - within this `impl Future` ... LL | is_qux(bar()); | ^^^^^ unsatisfied trait bound diff --git a/tests/ui/async-await/issues/issue-67893.stderr b/tests/ui/async-await/issues/issue-67893.stderr index 34f28dd53c7b9..610ed60bc8fda 100644 --- a/tests/ui/async-await/issues/issue-67893.stderr +++ b/tests/ui/async-await/issues/issue-67893.stderr @@ -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` + | - within this `impl Future` | = help: within `impl Future`, the trait `Send` is not implemented for `std::sync::MutexGuard<'_, ()>` note: required because it's used within this `async` fn body diff --git a/tests/ui/async-await/partial-drop-partial-reinit.stderr b/tests/ui/async-await/partial-drop-partial-reinit.stderr index cef835f7aed8b..cf4b408ad12b8 100644 --- a/tests/ui/async-await/partial-drop-partial-reinit.stderr +++ b/tests/ui/async-await/partial-drop-partial-reinit.stderr @@ -7,7 +7,7 @@ LL | gimme_send(foo()); | required by a bound introduced by this call ... LL | async fn foo() { - | -------------- within this `impl Future` + | - within this `impl Future` | help: within `impl Future`, the trait `Send` is not implemented for `NotSend` --> $DIR/partial-drop-partial-reinit.rs:19:1 diff --git a/tests/ui/c-variadic/not-async.stderr b/tests/ui/c-variadic/not-async.stderr index eab4c4f0822c4..2e584df55fdd7 100644 --- a/tests/ui/c-variadic/not-async.stderr +++ b/tests/ui/c-variadic/not-async.stderr @@ -14,9 +14,9 @@ error[E0700]: hidden type for `impl Future` 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 `'_` @@ -24,9 +24,9 @@ error[E0700]: hidden type for `impl Future` captures lifetime that --> $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 `'_` diff --git a/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr b/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr index 19ffff9d3f2bd..75d7224020969 100644 --- a/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr +++ b/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr @@ -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 diff --git a/tests/ui/inference/note-and-explain-ReVar-124973.stderr b/tests/ui/inference/note-and-explain-ReVar-124973.stderr index 964fbc4a4fb7a..443cbb81302f2 100644 --- a/tests/ui/inference/note-and-explain-ReVar-124973.stderr +++ b/tests/ui/inference/note-and-explain-ReVar-124973.stderr @@ -8,9 +8,9 @@ error[E0700]: hidden type for `impl Future` 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 `'_` diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr index 945d38d17f63d..bb8e847242571 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr @@ -34,24 +34,18 @@ LL | for<'a> >::Output: Future + '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) -... | -LL | | F:, -LL | | for<'a> >::Output: Future + 'a, - | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` +LL | async fn wrapper(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) -... | -LL | | F:, -LL | | for<'a> >::Output: Future + 'a, - | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` +LL | async fn wrapper(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` diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr index 15902bf16de5c..c325718b3033e 100644 --- a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr +++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr @@ -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: '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 diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index 2aacf9698379b..87313e3495249 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -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 diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed b/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed new file mode 100644 index 0000000000000..ba94e1967df39 --- /dev/null +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed @@ -0,0 +1,39 @@ +//@ run-rustfix +type T = dyn core::fmt::Debug; +//~^ NOTE this type alias is unsized +//~| NOTE this type alias is unsized +//~| NOTE this type alias is unsized + +fn f() -> Box { loop {} } +//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time +//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` +//~| NOTE doesn't have a size known at compile-time +//~| NOTE the return type of a function must have a statically known size +//~| HELP consider boxing the return type + +trait X { + fn f(&self) -> Box { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + +impl X for () { + fn f(&self) -> Box { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + +fn main() { + f(); + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + ().f(); +} diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs new file mode 100644 index 0000000000000..76f6e7c443424 --- /dev/null +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs @@ -0,0 +1,39 @@ +//@ run-rustfix +type T = dyn core::fmt::Debug; +//~^ NOTE this type alias is unsized +//~| NOTE this type alias is unsized +//~| NOTE this type alias is unsized + +fn f() -> T { loop {} } +//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time +//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` +//~| NOTE doesn't have a size known at compile-time +//~| NOTE the return type of a function must have a statically known size +//~| HELP consider boxing the return type + +trait X { + fn f(&self) -> T { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + +impl X for () { + fn f(&self) -> T { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + +fn main() { + f(); + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + ().f(); +} diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr new file mode 100644 index 0000000000000..bb6951687048f --- /dev/null +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr @@ -0,0 +1,66 @@ +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:7:11 + | +LL | fn f() -> T { loop {} } + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: this type alias is unsized + --> $DIR/dyn-trait-type-alias-return-type.rs:2:1 + | +LL | type T = dyn core::fmt::Debug; + | ^^^^^^ + = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` + | +LL | fn f() -> Box { loop {} } + | ++++ + + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:24:20 + | +LL | fn f(&self) -> T { loop {} } + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: this type alias is unsized + --> $DIR/dyn-trait-type-alias-return-type.rs:2:1 + | +LL | type T = dyn core::fmt::Debug; + | ^^^^^^ + = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` + | +LL | fn f(&self) -> Box { loop {} } + | ++++ + + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:15:20 + | +LL | fn f(&self) -> T { loop {} } + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: this type alias is unsized + --> $DIR/dyn-trait-type-alias-return-type.rs:2:1 + | +LL | type T = dyn core::fmt::Debug; + | ^^^^^^ + = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` + | +LL | fn f(&self) -> Box { loop {} } + | ++++ + + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:33:5 + | +LL | f(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` + = note: the return type of a function must have a statically known size + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unsized/issue-91801.rs b/tests/ui/unsized/issue-91801.rs index d906a08a55a21..8b4a3d214d5e7 100644 --- a/tests/ui/unsized/issue-91801.rs +++ b/tests/ui/unsized/issue-91801.rs @@ -6,7 +6,7 @@ pub static ALL_VALIDATORS: &[(&'static str, &'static Validator)] = &[("validate that credits and debits balance", &validate_something)]; fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> { - //~^ ERROR return type cannot be a trait object without pointer indirection + //~^ ERROR E0277 return Box::new(move |something: &'_ Something| -> Result<(), ()> { first(something).or_else(|_| second(something)) }); diff --git a/tests/ui/unsized/issue-91801.stderr b/tests/ui/unsized/issue-91801.stderr index 28e10f9caa41a..192cdc767dd90 100644 --- a/tests/ui/unsized/issue-91801.stderr +++ b/tests/ui/unsized/issue-91801.stderr @@ -1,18 +1,21 @@ -error[E0746]: return type cannot be a trait object without pointer indirection +error[E0277]: the size for values of type `(dyn Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a)` cannot be known at compilation time --> $DIR/issue-91801.rs:8:77 | LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> { | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: consider returning an `impl Trait` instead of a `dyn Trait` + = help: the trait `Sized` is not implemented for `(dyn Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a)` +note: this type alias is unsized + --> $DIR/issue-91801.rs:3:1 | -LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> impl Validator<'a> { - | ++++ -help: alternatively, box the return type, and wrap all of the returned values in `Box::new` +LL | type Validator<'a> = dyn 'a + Send + Sync + Fn(&'a Something) -> Result<(), ()>; + | ^^^^^^^^^^^^^^^^^^ + = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` | -LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box> { - | +++++++ + +LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box> { + | ++++ + error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0746`. +For more information about this error, try `rustc --explain E0277`.