Skip to content

Commit

Permalink
Split out async_fn_in_trait into a separate feature
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ComputerDruid committed Sep 22, 2022
1 parent 9062b78 commit d0a0749
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 19 deletions.
23 changes: 18 additions & 5 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,15 @@ impl FnDeclKind {
_ => false,
}
}

fn async_fn_allowed(&self, tcx: TyCtxt<'_>) -> bool {
match self {
FnDeclKind::Fn | FnDeclKind::Inherent => true,
FnDeclKind::Impl if tcx.features().async_fn_in_trait => true,
FnDeclKind::Trait if tcx.features().async_fn_in_trait => true,
_ => false,
}
}
}

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

let output = if let Some((ret_id, span)) = make_ret_async {
if !kind.impl_trait_allowed(self.tcx) {
if !kind.async_fn_allowed(self.tcx) {
match kind {
FnDeclKind::Trait | FnDeclKind::Impl => {
self.tcx
.sess
.create_feature_err(
TraitFnAsync { fn_span, span },
sym::return_position_impl_trait_in_trait,
sym::async_fn_in_trait,
)
.emit();
}
Expand Down Expand Up @@ -1917,9 +1926,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let future_bound = this.lower_async_fn_output_type_to_future_bound(
output,
span,
ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
in_trait,
if in_trait && !this.tcx.features().return_position_impl_trait_in_trait {
ImplTraitContext::Disallowed(ImplTraitPosition::TraitReturn)
} else {
ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
in_trait,
}
},
);

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ declare_features! (
(active, associated_type_defaults, "1.2.0", Some(29661), None),
/// Allows `async || body` closures.
(active, async_closure, "1.37.0", Some(62290), None),
/// Alows async functions to be declared, implemented, and used in traits.
(incomplete, async_fn_in_trait, "CURRENT_RUSTC_VERSION", Some(91611), None),
/// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries.
(active, c_unwind, "1.52.0", Some(74990), None),
/// Allows using C-variadics.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ symbols! {
assume_init,
async_await,
async_closure,
async_fn_in_trait,
atomic,
atomic_mod,
atomics,
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/async-await/async-trait-fn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ LL | async fn foo() {}
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable

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

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

error[E0308]: mismatched types
--> $DIR/async-trait-fn.rs:3:20
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/async-await/edition-deny-async-fns-2015.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ LL | async fn foo() {}
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable

error[E0308]: mismatched types
--> $DIR/edition-deny-async-fns-2015.rs:18:20
Expand Down
25 changes: 25 additions & 0 deletions src/test/ui/async-await/feature-gate-async_fn_in_trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// edition:2021

// RPITIT is not enough to allow use of async functions
#![allow(incomplete_features)]
#![feature(return_position_impl_trait_in_trait)]

trait T {
async fn foo(); //~ ERROR functions in traits cannot be declared `async`
}

// Both return_position_impl_trait_in_trait and async_fn_in_trait are required for this (see also
// feature-gate-return_position_impl_trait_in_trait.rs)
trait T2 {
async fn foo() -> impl Sized; //~ ERROR functions in traits cannot be declared `async`
}

trait T3 {
fn foo() -> impl std::future::Future<Output = ()>;
}

impl T3 for () {
async fn foo() {} //~ ERROR functions in traits cannot be declared `async`
}

fn main() {}
42 changes: 42 additions & 0 deletions src/test/ui/async-await/feature-gate-async_fn_in_trait.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
error[E0706]: functions in traits cannot be declared `async`
--> $DIR/feature-gate-async_fn_in_trait.rs:8:5
|
LL | async fn foo();
| -----^^^^^^^^^^
| |
| `async` because of this
|
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable

error[E0706]: functions in traits cannot be declared `async`
--> $DIR/feature-gate-async_fn_in_trait.rs:14:5
|
LL | async fn foo() -> impl Sized;
| -----^^^^^^^^^^^^^^^^^^^^^^^^
| |
| `async` because of this
|
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable

error[E0706]: functions in traits cannot be declared `async`
--> $DIR/feature-gate-async_fn_in_trait.rs:22:5
|
LL | async fn foo() {}
| -----^^^^^^^^^
| |
| `async` because of this
|
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0706`.
2 changes: 1 addition & 1 deletion src/test/ui/async-await/issues/issue-95307.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ LL | async fn new() -> [u8; _];
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/issue-95307.rs:7:28
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
// edition:2021

// async_fn_in_trait is not enough to allow use of RPITIT
#![allow(incomplete_features)]
#![feature(async_fn_in_trait)]

trait Foo {
fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return
fn baz() -> Box<impl std::fmt::Display>; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return
}

// Both return_position_impl_trait_in_trait and async_fn_in_trait are required for this (see also
// feature-gate-async_fn_in_trait.rs)
trait AsyncFoo {
async fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return
}

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

error: aborting due to previous error
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
--> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:9:21
|
LL | fn baz() -> Box<impl std::fmt::Display>;
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
--> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:15:23
|
LL | async fn bar() -> impl Sized;
| ^^^^^^^^^^
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0562`.
8 changes: 4 additions & 4 deletions src/test/ui/parser/fn-header-semantic-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ LL | async fn ft1();
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable

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

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

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

error[E0391]: cycle detected when computing type of `main::ff5::{opaque#0}`
--> $DIR/fn-header-semantic-fail.rs:12:44
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ LL | async fn associated();
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable

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

error: aborting due to 5 previous errors

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

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

0 comments on commit d0a0749

Please sign in to comment.