Skip to content

Commit 16cbdd0

Browse files
Allow desugaring async fn in trait to compatible, concrete future types
1 parent ea37e80 commit 16cbdd0

9 files changed

+15
-77
lines changed

compiler/rustc_hir_analysis/messages.ftl

-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the as
3333
3434
hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion = use a fully qualified path with explicit lifetimes
3535
36-
hir_analysis_async_trait_impl_should_be_async =
37-
method `{$method_name}` should be async because the method from the trait is async
38-
.trait_item_label = required because the trait method is async
39-
4036
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
4137
.label = deref recursion limit reached
4238
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

-31
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ fn check_method_is_structurally_compatible<'tcx>(
7474
compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?;
7575
compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?;
7676
compare_synthetic_generics(tcx, impl_m, trait_m, delay)?;
77-
compare_asyncness(tcx, impl_m, trait_m, delay)?;
7877
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?;
7978
Ok(())
8079
}
@@ -414,36 +413,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
414413
}
415414
}
416415

417-
fn compare_asyncness<'tcx>(
418-
tcx: TyCtxt<'tcx>,
419-
impl_m: ty::AssocItem,
420-
trait_m: ty::AssocItem,
421-
delay: bool,
422-
) -> Result<(), ErrorGuaranteed> {
423-
if tcx.asyncness(trait_m.def_id).is_async() {
424-
match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() {
425-
ty::Alias(ty::Opaque, ..) => {
426-
// allow both `async fn foo()` and `fn foo() -> impl Future`
427-
}
428-
ty::Error(_) => {
429-
// We don't know if it's ok, but at least it's already an error.
430-
}
431-
_ => {
432-
return Err(tcx
433-
.dcx()
434-
.create_err(crate::errors::AsyncTraitImplShouldBeAsync {
435-
span: tcx.def_span(impl_m.def_id),
436-
method_name: trait_m.name,
437-
trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
438-
})
439-
.emit_unless(delay));
440-
}
441-
};
442-
}
443-
444-
Ok(())
445-
}
446-
447416
/// Given a method def-id in an impl, compare the method signature of the impl
448417
/// against the trait that it's implementing. In doing so, infer the hidden types
449418
/// that this method's signature provides to satisfy each return-position `impl Trait`

compiler/rustc_hir_analysis/src/errors.rs

-11
Original file line numberDiff line numberDiff line change
@@ -166,17 +166,6 @@ pub struct LifetimesOrBoundsMismatchOnTrait {
166166
pub ident: Ident,
167167
}
168168

169-
#[derive(Diagnostic)]
170-
#[diag(hir_analysis_async_trait_impl_should_be_async)]
171-
pub struct AsyncTraitImplShouldBeAsync {
172-
#[primary_span]
173-
// #[label]
174-
pub span: Span,
175-
#[label(hir_analysis_trait_item_label)]
176-
pub trait_item_span: Option<Span>,
177-
pub method_name: Symbol,
178-
}
179-
180169
#[derive(Diagnostic)]
181170
#[diag(hir_analysis_drop_impl_on_wrong_item, code = E0120)]
182171
pub struct DropImplOnWrongItem {

tests/ui/async-await/in-trait/async-example-desugared-boxed.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// edition: 2021
2+
// check-pass
23

34
use std::future::Future;
45
use std::pin::Pin;
@@ -9,7 +10,6 @@ trait MyTrait {
910

1011
impl MyTrait for i32 {
1112
fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
12-
//~^ ERROR method `foo` should be async
1313
Box::pin(async { *self })
1414
}
1515
}

tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr

-11
This file was deleted.

tests/ui/async-await/in-trait/async-example-desugared-manual.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// edition: 2021
2+
// check-pass
23

34
use std::future::Future;
45
use std::task::Poll;
@@ -17,7 +18,6 @@ impl Future for MyFuture {
1718

1819
impl MyTrait for u32 {
1920
fn foo(&self) -> MyFuture {
20-
//~^ ERROR method `foo` should be async
2121
MyFuture
2222
}
2323
}

tests/ui/async-await/in-trait/async-example-desugared-manual.stderr

-11
This file was deleted.

tests/ui/async-await/in-trait/fn-not-async-err.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ trait MyTrait {
88

99
impl MyTrait for i32 {
1010
fn foo(&self) -> i32 {
11-
//~^ ERROR: method `foo` should be async
11+
//~^ ERROR: `i32` is not a future
1212
*self
1313
}
1414
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
error: method `foo` should be async because the method from the trait is async
2-
--> $DIR/fn-not-async-err.rs:10:5
1+
error[E0277]: `i32` is not a future
2+
--> $DIR/fn-not-async-err.rs:10:22
33
|
4-
LL | async fn foo(&self) -> i32;
5-
| --------------------------- required because the trait method is async
6-
...
74
LL | fn foo(&self) -> i32 {
8-
| ^^^^^^^^^^^^^^^^^^^^
5+
| ^^^ `i32` is not a future
6+
|
7+
= help: the trait `Future` is not implemented for `i32`
8+
= note: i32 must be a future or must implement `IntoFuture` to be awaited
9+
note: required by a bound in `MyTrait::{opaque#0}`
10+
--> $DIR/fn-not-async-err.rs:6:5
11+
|
12+
LL | async fn foo(&self) -> i32;
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `MyTrait::{opaque#0}`
914

1015
error: aborting due to 1 previous error
1116

17+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)