Skip to content

Commit d0a0749

Browse files
committed
Split out async_fn_in_trait into a separate feature
PR #101224 added support for async fn in trait desuraging behind the return_position_impl_trait_in_trait feature. Split this out so that it's behind its own feature gate, since async fn in trait doesn't need to follow the same stabilization schedule.
1 parent 9062b78 commit d0a0749

13 files changed

+133
-19
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,15 @@ impl FnDeclKind {
332332
_ => false,
333333
}
334334
}
335+
336+
fn async_fn_allowed(&self, tcx: TyCtxt<'_>) -> bool {
337+
match self {
338+
FnDeclKind::Fn | FnDeclKind::Inherent => true,
339+
FnDeclKind::Impl if tcx.features().async_fn_in_trait => true,
340+
FnDeclKind::Trait if tcx.features().async_fn_in_trait => true,
341+
_ => false,
342+
}
343+
}
335344
}
336345

337346
#[derive(Copy, Clone)]
@@ -1692,14 +1701,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16921701
}));
16931702

16941703
let output = if let Some((ret_id, span)) = make_ret_async {
1695-
if !kind.impl_trait_allowed(self.tcx) {
1704+
if !kind.async_fn_allowed(self.tcx) {
16961705
match kind {
16971706
FnDeclKind::Trait | FnDeclKind::Impl => {
16981707
self.tcx
16991708
.sess
17001709
.create_feature_err(
17011710
TraitFnAsync { fn_span, span },
1702-
sym::return_position_impl_trait_in_trait,
1711+
sym::async_fn_in_trait,
17031712
)
17041713
.emit();
17051714
}
@@ -1917,9 +1926,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19171926
let future_bound = this.lower_async_fn_output_type_to_future_bound(
19181927
output,
19191928
span,
1920-
ImplTraitContext::ReturnPositionOpaqueTy {
1921-
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
1922-
in_trait,
1929+
if in_trait && !this.tcx.features().return_position_impl_trait_in_trait {
1930+
ImplTraitContext::Disallowed(ImplTraitPosition::TraitReturn)
1931+
} else {
1932+
ImplTraitContext::ReturnPositionOpaqueTy {
1933+
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
1934+
in_trait,
1935+
}
19231936
},
19241937
);
19251938

compiler/rustc_feature/src/active.rs

+2
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ declare_features! (
312312
(active, associated_type_defaults, "1.2.0", Some(29661), None),
313313
/// Allows `async || body` closures.
314314
(active, async_closure, "1.37.0", Some(62290), None),
315+
/// Alows async functions to be declared, implemented, and used in traits.
316+
(incomplete, async_fn_in_trait, "CURRENT_RUSTC_VERSION", Some(91611), None),
315317
/// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries.
316318
(active, c_unwind, "1.52.0", Some(74990), None),
317319
/// Allows using C-variadics.

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ symbols! {
396396
assume_init,
397397
async_await,
398398
async_closure,
399+
async_fn_in_trait,
399400
atomic,
400401
atomic_mod,
401402
atomics,

src/test/ui/async-await/async-trait-fn.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | async fn foo() {}
99
= note: `async` trait functions are not currently supported
1010
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
1111
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
12-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
12+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
1313

1414
error[E0706]: functions in traits cannot be declared `async`
1515
--> $DIR/async-trait-fn.rs:5:5
@@ -22,7 +22,7 @@ LL | async fn bar(&self) {}
2222
= note: `async` trait functions are not currently supported
2323
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
2424
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
25-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
25+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
2626

2727
error[E0706]: functions in traits cannot be declared `async`
2828
--> $DIR/async-trait-fn.rs:7:5
@@ -35,7 +35,7 @@ LL | async fn baz() {
3535
= note: `async` trait functions are not currently supported
3636
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
3737
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
38-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
38+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
3939

4040
error[E0308]: mismatched types
4141
--> $DIR/async-trait-fn.rs:3:20

src/test/ui/async-await/edition-deny-async-fns-2015.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ LL | async fn foo() {}
9090
= note: `async` trait functions are not currently supported
9191
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
9292
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
93-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
93+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
9494

9595
error[E0308]: mismatched types
9696
--> $DIR/edition-deny-async-fns-2015.rs:18:20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// edition:2021
2+
3+
// RPITIT is not enough to allow use of async functions
4+
#![allow(incomplete_features)]
5+
#![feature(return_position_impl_trait_in_trait)]
6+
7+
trait T {
8+
async fn foo(); //~ ERROR functions in traits cannot be declared `async`
9+
}
10+
11+
// Both return_position_impl_trait_in_trait and async_fn_in_trait are required for this (see also
12+
// feature-gate-return_position_impl_trait_in_trait.rs)
13+
trait T2 {
14+
async fn foo() -> impl Sized; //~ ERROR functions in traits cannot be declared `async`
15+
}
16+
17+
trait T3 {
18+
fn foo() -> impl std::future::Future<Output = ()>;
19+
}
20+
21+
impl T3 for () {
22+
async fn foo() {} //~ ERROR functions in traits cannot be declared `async`
23+
}
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
error[E0706]: functions in traits cannot be declared `async`
2+
--> $DIR/feature-gate-async_fn_in_trait.rs:8:5
3+
|
4+
LL | async fn foo();
5+
| -----^^^^^^^^^^
6+
| |
7+
| `async` because of this
8+
|
9+
= note: `async` trait functions are not currently supported
10+
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
11+
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
12+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
13+
14+
error[E0706]: functions in traits cannot be declared `async`
15+
--> $DIR/feature-gate-async_fn_in_trait.rs:14:5
16+
|
17+
LL | async fn foo() -> impl Sized;
18+
| -----^^^^^^^^^^^^^^^^^^^^^^^^
19+
| |
20+
| `async` because of this
21+
|
22+
= note: `async` trait functions are not currently supported
23+
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
24+
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
25+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
26+
27+
error[E0706]: functions in traits cannot be declared `async`
28+
--> $DIR/feature-gate-async_fn_in_trait.rs:22:5
29+
|
30+
LL | async fn foo() {}
31+
| -----^^^^^^^^^
32+
| |
33+
| `async` because of this
34+
|
35+
= note: `async` trait functions are not currently supported
36+
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
37+
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
38+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
39+
40+
error: aborting due to 3 previous errors
41+
42+
For more information about this error, try `rustc --explain E0706`.

src/test/ui/async-await/issues/issue-95307.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | async fn new() -> [u8; _];
99
= note: `async` trait functions are not currently supported
1010
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
1111
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
12-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
12+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
1313

1414
error: in expressions, `_` can only be used on the left-hand side of an assignment
1515
--> $DIR/issue-95307.rs:7:28
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1+
// edition:2021
2+
3+
// async_fn_in_trait is not enough to allow use of RPITIT
4+
#![allow(incomplete_features)]
5+
#![feature(async_fn_in_trait)]
6+
17
trait Foo {
28
fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return
9+
fn baz() -> Box<impl std::fmt::Display>; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return
10+
}
11+
12+
// Both return_position_impl_trait_in_trait and async_fn_in_trait are required for this (see also
13+
// feature-gate-async_fn_in_trait.rs)
14+
trait AsyncFoo {
15+
async fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return
316
}
417

518
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,30 @@
11
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
2-
--> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:2:17
2+
--> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:8:17
33
|
44
LL | fn bar() -> impl Sized;
55
| ^^^^^^^^^^
66
|
77
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
88
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
99

10-
error: aborting due to previous error
10+
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
11+
--> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:9:21
12+
|
13+
LL | fn baz() -> Box<impl std::fmt::Display>;
14+
| ^^^^^^^^^^^^^^^^^^^^^^
15+
|
16+
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
17+
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
18+
19+
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
20+
--> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:15:23
21+
|
22+
LL | async fn bar() -> impl Sized;
23+
| ^^^^^^^^^^
24+
|
25+
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
26+
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
27+
28+
error: aborting due to 3 previous errors
1129

1230
For more information about this error, try `rustc --explain E0562`.

src/test/ui/parser/fn-header-semantic-fail.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ LL | async fn ft1();
147147
= note: `async` trait functions are not currently supported
148148
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
149149
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
150-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
150+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
151151

152152
error[E0706]: functions in traits cannot be declared `async`
153153
--> $DIR/fn-header-semantic-fail.rs:21:9
@@ -160,7 +160,7 @@ LL | const async unsafe extern "C" fn ft5();
160160
= note: `async` trait functions are not currently supported
161161
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
162162
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
163-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
163+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
164164

165165
error[E0706]: functions in traits cannot be declared `async`
166166
--> $DIR/fn-header-semantic-fail.rs:29:9
@@ -173,7 +173,7 @@ LL | async fn ft1() {}
173173
= note: `async` trait functions are not currently supported
174174
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
175175
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
176-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
176+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
177177

178178
error[E0706]: functions in traits cannot be declared `async`
179179
--> $DIR/fn-header-semantic-fail.rs:33:9
@@ -186,7 +186,7 @@ LL | const async unsafe extern "C" fn ft5() {}
186186
= note: `async` trait functions are not currently supported
187187
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
188188
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
189-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
189+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
190190

191191
error[E0391]: cycle detected when computing type of `main::ff5::{opaque#0}`
192192
--> $DIR/fn-header-semantic-fail.rs:12:44

src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ LL | async fn associated();
3333
= note: `async` trait functions are not currently supported
3434
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
3535
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
36-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
36+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
3737

3838
error[E0706]: functions in traits cannot be declared `async`
3939
--> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
@@ -46,7 +46,7 @@ LL | async fn associated();
4646
= note: `async` trait functions are not currently supported
4747
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
4848
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
49-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
49+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
5050

5151
error: aborting due to 5 previous errors
5252

src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ LL | trait C{async fn new(val: T) {}
5151
= note: `async` trait functions are not currently supported
5252
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
5353
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
54-
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
54+
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
5555

5656
warning: changes to closure capture in Rust 2021 will affect drop order
5757
--> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:6:57

0 commit comments

Comments
 (0)