From 16cbdd0321f342093b71026dc1c5126606e4abe9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 18 Jan 2024 16:39:20 +0000 Subject: [PATCH] Allow desugaring async fn in trait to compatible, concrete future types --- compiler/rustc_hir_analysis/messages.ftl | 4 --- .../src/check/compare_impl_item.rs | 31 ------------------- compiler/rustc_hir_analysis/src/errors.rs | 11 ------- .../in-trait/async-example-desugared-boxed.rs | 2 +- .../async-example-desugared-boxed.stderr | 11 ------- .../async-example-desugared-manual.rs | 2 +- .../async-example-desugared-manual.stderr | 11 ------- .../async-await/in-trait/fn-not-async-err.rs | 2 +- .../in-trait/fn-not-async-err.stderr | 18 +++++++---- 9 files changed, 15 insertions(+), 77 deletions(-) delete mode 100644 tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr delete mode 100644 tests/ui/async-await/in-trait/async-example-desugared-manual.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 54d0fb6ffab..d0fb0e3fb76 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -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_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}` .label = deref recursion limit reached .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 379c1154e5f..f9c1ed0e0e1 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -74,7 +74,6 @@ fn check_method_is_structurally_compatible<'tcx>( compare_generic_param_kinds(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_asyncness(tcx, impl_m, trait_m, delay)?; check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?; 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 /// 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` diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 4eba31e327f..8b8c0f7ff8d 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -166,17 +166,6 @@ pub struct LifetimesOrBoundsMismatchOnTrait { 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, - pub method_name: Symbol, -} - #[derive(Diagnostic)] #[diag(hir_analysis_drop_impl_on_wrong_item, code = E0120)] pub struct DropImplOnWrongItem { diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs b/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs index c5a9841029e..4008e09998e 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs @@ -1,4 +1,5 @@ // edition: 2021 +// check-pass use std::future::Future; use std::pin::Pin; @@ -9,7 +10,6 @@ trait MyTrait { impl MyTrait for i32 { fn foo(&self) -> Pin + '_>> { - //~^ ERROR method `foo` should be async Box::pin(async { *self }) } } 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 deleted file mode 100644 index 1462c694e16..00000000000 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr +++ /dev/null @@ -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 + '_>> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.rs b/tests/ui/async-await/in-trait/async-example-desugared-manual.rs index c287b9a5b84..75f4ba1d076 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.rs @@ -1,4 +1,5 @@ // edition: 2021 +// check-pass use std::future::Future; 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 { fn foo(&self) -> MyFuture { - //~^ ERROR method `foo` should be async MyFuture } } 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 deleted file mode 100644 index a2f1060e36f..00000000000 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr +++ /dev/null @@ -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 - diff --git a/tests/ui/async-await/in-trait/fn-not-async-err.rs b/tests/ui/async-await/in-trait/fn-not-async-err.rs index 60077a7e00c..6261ed1f1b7 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err.rs +++ b/tests/ui/async-await/in-trait/fn-not-async-err.rs @@ -8,7 +8,7 @@ trait MyTrait { impl MyTrait for i32 { fn foo(&self) -> i32 { - //~^ ERROR: method `foo` should be async + //~^ ERROR: `i32` is not a future *self } } diff --git a/tests/ui/async-await/in-trait/fn-not-async-err.stderr b/tests/ui/async-await/in-trait/fn-not-async-err.stderr index f75ccb65d15..dc46077d583 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err.stderr +++ b/tests/ui/async-await/in-trait/fn-not-async-err.stderr @@ -1,11 +1,17 @@ -error: method `foo` should be async because the method from the trait is async - --> $DIR/fn-not-async-err.rs:10:5 +error[E0277]: `i32` is not a future + --> $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; - | --------------------------- required because the trait method is async -... -LL | fn foo(&self) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `MyTrait::{opaque#0}` error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`.