mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Recognize type Alias = dyn Trait in fn return types
```
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:4: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:1:1
|
LL | type T = dyn core::fmt::Debug;
| ^^^^^^
= note: the return type of a function must have a statically known size
```
This commit is contained in:
@@ -1886,6 +1886,19 @@ pub(super) fn suggest_impl_trait(
|
||||
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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
type T = dyn core::fmt::Debug;
|
||||
|
||||
//~^ NOTE this type alias is unsized
|
||||
|
||||
fn f() -> T { loop {} }
|
||||
//~^ ERROR return type cannot be a trait object without pointer indirection
|
||||
//~| HELP
|
||||
//~| HELP
|
||||
//~^ 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
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||
--> $DIR/dyn-trait-type-alias-return-type.rs:3:11
|
||||
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:4:11
|
||||
|
|
||||
LL | fn f() -> T { loop {} }
|
||||
| ^ 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 Debug + 'static)`
|
||||
note: this type alias is unsized
|
||||
--> $DIR/dyn-trait-type-alias-return-type.rs:1:1
|
||||
|
|
||||
LL | fn f() -> impl T { loop {} }
|
||||
| ++++
|
||||
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
||||
|
|
||||
LL | fn f() -> Box<dyn T> { Box::new(loop {}) }
|
||||
| +++++++ + +++++++++ +
|
||||
LL | type T = dyn core::fmt::Debug;
|
||||
| ^^^^^^
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
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`.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
&[("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,17 @@
|
||||
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 | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box<dyn Validator<'a>> {
|
||||
| +++++++ +
|
||||
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
|
||||
|
||||
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`.
|
||||
|
||||
Reference in New Issue
Block a user