Rollup merge of #148491 - estebank:issue-147894, r=jackh726
Correctly provide suggestions when encountering `async fn` with a `dyn Trait` return type
Point at return type of `async fn`s instead of their def `Span`.
Correctly provide suggestions when encountering `async fn` with a `dyn Trait` return type.
Correctly address `type Alias = dyn Trait` when `fn foo() -> Alias { .. }`.
Fix rust-lang/rust#147894.
This commit is contained in:
commit
8a4312a069
30 changed files with 393 additions and 108 deletions
|
|
@ -1670,7 +1670,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) => {
|
||||
|
|
@ -1755,9 +1755,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),
|
||||
|
|
|
|||
|
|
@ -1886,12 +1886,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<dyn { .. }>
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -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<usize>) -> 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<usize>) -> 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<usize>) -> 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<usize>) -> bool {
|
|||
= note: `std::cell::Cell<usize>` 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) -> T
|
||||
LL | |
|
||||
LL | | where
|
||||
LL | | T: Send,
|
||||
| |____________^ future returned by `generic_future` is not `Send`
|
||||
LL | async fn generic_future<T>(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<T>(_: Rc<T>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
30
tests/ui/async-await/async-fn/dyn-in-return-type.fixed
Normal file
30
tests/ui/async-await/async-fn/dyn-in-return-type.fixed
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//@ edition:2024
|
||||
//@ run-rustfix
|
||||
|
||||
async fn f() -> Box<impl 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) -> Box<impl 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) -> Box<impl 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();
|
||||
}
|
||||
30
tests/ui/async-await/async-fn/dyn-in-return-type.rs
Normal file
30
tests/ui/async-await/async-fn/dyn-in-return-type.rs
Normal file
|
|
@ -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();
|
||||
}
|
||||
51
tests/ui/async-await/async-fn/dyn-in-return-type.stderr
Normal file
51
tests/ui/async-await/async-fn/dyn-in-return-type.stderr
Normal file
|
|
@ -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<dyn core::fmt::Debug> {
|
||||
| ++++ +
|
||||
|
||||
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<dyn core::fmt::Debug> {
|
||||
| ++++ +
|
||||
|
||||
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<dyn core::fmt::Debug> {
|
||||
| ++++ +
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0746`.
|
||||
|
|
@ -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 `()`
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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> + '_>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
| ^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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>`
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that
|
|||
--> $DIR/not-async.rs:5:65
|
||||
|
|
||||
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<Output = ()>` captures lifetime that
|
|||
--> $DIR/not-async.rs:12:73
|
||||
|
|
||||
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 `'_`
|
||||
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...)
|
|||
= help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
|
||||
|
||||
error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures
|
||||
--> $DIR/c-variadic.rs:26:1
|
||||
--> $DIR/c-variadic.rs:26:69
|
||||
|
|
||||
LL | async unsafe extern "cmse-nonsecure-entry" fn async_is_not_allowed() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that
|
|||
--> $DIR/note-and-explain-ReVar-124973.rs:5:76
|
||||
|
|
||||
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 `'_`
|
||||
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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
|
||||
--> $DIR/type-match-with-late-bound.rs:8:32
|
||||
|
|
||||
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...
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
39
tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed
Normal file
39
tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed
Normal file
|
|
@ -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<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) -> Box<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) -> Box<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();
|
||||
}
|
||||
39
tests/ui/type-alias/dyn-trait-type-alias-return-type.rs
Normal file
39
tests/ui/type-alias/dyn-trait-type-alias-return-type.rs
Normal file
|
|
@ -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();
|
||||
}
|
||||
66
tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr
Normal file
66
tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr
Normal file
|
|
@ -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<T> { 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<T> { 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<T> { 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`.
|
||||
|
|
@ -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))
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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<dyn Validator<'a>> {
|
||||
| +++++++ +
|
||||
LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box<Validator<'a>> {
|
||||
| ++++ +
|
||||
|
||||
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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue