Allow desugaring async fn in trait to compatible, concrete future types
This commit is contained in:
parent
ea37e8091f
commit
16cbdd0321
@ -33,10 +33,6 @@ hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the as
|
|||||||
|
|
||||||
hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion = use a fully qualified path with explicit lifetimes
|
hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion = use a fully qualified path with explicit lifetimes
|
||||||
|
|
||||||
hir_analysis_async_trait_impl_should_be_async =
|
|
||||||
method `{$method_name}` should be async because the method from the trait is async
|
|
||||||
.trait_item_label = required because the trait method is async
|
|
||||||
|
|
||||||
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
|
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
|
||||||
.label = deref recursion limit reached
|
.label = deref recursion limit reached
|
||||||
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
|
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
|
||||||
|
@ -74,7 +74,6 @@ fn check_method_is_structurally_compatible<'tcx>(
|
|||||||
compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?;
|
compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?;
|
||||||
compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?;
|
compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?;
|
||||||
compare_synthetic_generics(tcx, impl_m, trait_m, delay)?;
|
compare_synthetic_generics(tcx, impl_m, trait_m, delay)?;
|
||||||
compare_asyncness(tcx, impl_m, trait_m, delay)?;
|
|
||||||
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?;
|
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -414,36 +413,6 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compare_asyncness<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
impl_m: ty::AssocItem,
|
|
||||||
trait_m: ty::AssocItem,
|
|
||||||
delay: bool,
|
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
|
||||||
if tcx.asyncness(trait_m.def_id).is_async() {
|
|
||||||
match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() {
|
|
||||||
ty::Alias(ty::Opaque, ..) => {
|
|
||||||
// allow both `async fn foo()` and `fn foo() -> impl Future`
|
|
||||||
}
|
|
||||||
ty::Error(_) => {
|
|
||||||
// We don't know if it's ok, but at least it's already an error.
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(tcx
|
|
||||||
.dcx()
|
|
||||||
.create_err(crate::errors::AsyncTraitImplShouldBeAsync {
|
|
||||||
span: tcx.def_span(impl_m.def_id),
|
|
||||||
method_name: trait_m.name,
|
|
||||||
trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
|
|
||||||
})
|
|
||||||
.emit_unless(delay));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given a method def-id in an impl, compare the method signature of the impl
|
/// Given a method def-id in an impl, compare the method signature of the impl
|
||||||
/// against the trait that it's implementing. In doing so, infer the hidden types
|
/// against the trait that it's implementing. In doing so, infer the hidden types
|
||||||
/// that this method's signature provides to satisfy each return-position `impl Trait`
|
/// that this method's signature provides to satisfy each return-position `impl Trait`
|
||||||
|
@ -166,17 +166,6 @@ pub struct LifetimesOrBoundsMismatchOnTrait {
|
|||||||
pub ident: Ident,
|
pub ident: Ident,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_async_trait_impl_should_be_async)]
|
|
||||||
pub struct AsyncTraitImplShouldBeAsync {
|
|
||||||
#[primary_span]
|
|
||||||
// #[label]
|
|
||||||
pub span: Span,
|
|
||||||
#[label(hir_analysis_trait_item_label)]
|
|
||||||
pub trait_item_span: Option<Span>,
|
|
||||||
pub method_name: Symbol,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_drop_impl_on_wrong_item, code = E0120)]
|
#[diag(hir_analysis_drop_impl_on_wrong_item, code = E0120)]
|
||||||
pub struct DropImplOnWrongItem {
|
pub struct DropImplOnWrongItem {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// edition: 2021
|
// edition: 2021
|
||||||
|
// check-pass
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
@ -9,7 +10,6 @@ trait MyTrait {
|
|||||||
|
|
||||||
impl MyTrait for i32 {
|
impl MyTrait for i32 {
|
||||||
fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
|
fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
|
||||||
//~^ ERROR method `foo` should be async
|
|
||||||
Box::pin(async { *self })
|
Box::pin(async { *self })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
error: method `foo` should be async because the method from the trait is async
|
|
||||||
--> $DIR/async-example-desugared-boxed.rs:11:5
|
|
||||||
|
|
|
||||||
LL | async fn foo(&self) -> i32;
|
|
||||||
| --------------------------- required because the trait method is async
|
|
||||||
...
|
|
||||||
LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
|||||||
// edition: 2021
|
// edition: 2021
|
||||||
|
// check-pass
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
@ -17,7 +18,6 @@ fn poll(self: std::pin::Pin<&mut Self>, _: &mut std::task::Context<'_>) -> Poll<
|
|||||||
|
|
||||||
impl MyTrait for u32 {
|
impl MyTrait for u32 {
|
||||||
fn foo(&self) -> MyFuture {
|
fn foo(&self) -> MyFuture {
|
||||||
//~^ ERROR method `foo` should be async
|
|
||||||
MyFuture
|
MyFuture
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
error: method `foo` should be async because the method from the trait is async
|
|
||||||
--> $DIR/async-example-desugared-manual.rs:19:5
|
|
||||||
|
|
|
||||||
LL | async fn foo(&self) -> i32;
|
|
||||||
| --------------------------- required because the trait method is async
|
|
||||||
...
|
|
||||||
LL | fn foo(&self) -> MyFuture {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
@ -8,7 +8,7 @@ trait MyTrait {
|
|||||||
|
|
||||||
impl MyTrait for i32 {
|
impl MyTrait for i32 {
|
||||||
fn foo(&self) -> i32 {
|
fn foo(&self) -> i32 {
|
||||||
//~^ ERROR: method `foo` should be async
|
//~^ ERROR: `i32` is not a future
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
error: method `foo` should be async because the method from the trait is async
|
error[E0277]: `i32` is not a future
|
||||||
--> $DIR/fn-not-async-err.rs:10:5
|
--> $DIR/fn-not-async-err.rs:10:22
|
||||||
|
|
|
||||||
|
LL | fn foo(&self) -> i32 {
|
||||||
|
| ^^^ `i32` is not a future
|
||||||
|
|
|
||||||
|
= help: the trait `Future` is not implemented for `i32`
|
||||||
|
= note: i32 must be a future or must implement `IntoFuture` to be awaited
|
||||||
|
note: required by a bound in `MyTrait::{opaque#0}`
|
||||||
|
--> $DIR/fn-not-async-err.rs:6:5
|
||||||
|
|
|
|
||||||
LL | async fn foo(&self) -> i32;
|
LL | async fn foo(&self) -> i32;
|
||||||
| --------------------------- required because the trait method is async
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `MyTrait::{opaque#0}`
|
||||||
...
|
|
||||||
LL | fn foo(&self) -> i32 {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
Loading…
Reference in New Issue
Block a user