Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature gate async methods #60088

Merged
merged 8 commits into from
Apr 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ impl<'a> FnKind<'a> {
FnKind::Closure(attrs) => attrs,
}
}

pub fn header(&self) -> Option<FnHeader> {
match *self {
FnKind::ItemFn(_, _, header, _, _) => Some(header),
FnKind::Method(_, sig, _, _) => Some(sig.header),
FnKind::Closure(_) => None,
}
}
}

/// Specifies what nested things a visitor wants to visit. The most
Expand Down
18 changes: 3 additions & 15 deletions src/librustc/hir/map/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,27 +175,15 @@ impl<'a> FnLikeNode<'a> {
}

pub fn constness(self) -> ast::Constness {
match self.kind() {
FnKind::ItemFn(_, _, header, ..) => header.constness,
FnKind::Method(_, m, ..) => m.header.constness,
_ => ast::Constness::NotConst
}
self.kind().header().map_or(ast::Constness::NotConst, |header| header.constness)
}

pub fn asyncness(self) -> ast::IsAsync {
match self.kind() {
FnKind::ItemFn(_, _, header, ..) => header.asyncness,
FnKind::Method(_, m, ..) => m.header.asyncness,
_ => ast::IsAsync::NotAsync
}
self.kind().header().map_or(ast::IsAsync::NotAsync, |header| header.asyncness)
}

pub fn unsafety(self) -> ast::Unsafety {
match self.kind() {
FnKind::ItemFn(_, _, header, ..) => header.unsafety,
FnKind::Method(_, m, ..) => m.header.unsafety,
_ => ast::Unsafety::Normal
}
self.kind().header().map_or(ast::Unsafety::Normal, |header| header.unsafety)
}

pub fn kind(self) -> FnKind<'a> {
Expand Down
37 changes: 17 additions & 20 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2035,28 +2035,22 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn_decl: &'a ast::FnDecl,
span: Span,
_node_id: NodeId) {
match fn_kind {
FnKind::ItemFn(_, header, _, _) => {
// Check for const fn and async fn declarations.
if header.asyncness.node.is_async() {
gate_feature_post!(&self, async_await, span, "async fn is unstable");
}
if let Some(header) = fn_kind.header() {
// Check for const fn and async fn declarations.
if header.asyncness.node.is_async() {
gate_feature_post!(&self, async_await, span, "async fn is unstable");
}

if fn_decl.c_variadic {
gate_feature_post!(&self, c_variadic, span,
"C-varaidic functions are unstable");
}
// Stability of const fn methods are covered in
// `visit_trait_item` and `visit_impl_item` below; this is
// because default methods don't pass through this point.
// Stability of const fn methods are covered in
// `visit_trait_item` and `visit_impl_item` below; this is
// because default methods don't pass through this point.
self.check_abi(header.abi, span);
}

self.check_abi(header.abi, span);
}
FnKind::Method(_, sig, _, _) => {
self.check_abi(sig.header.abi, span);
}
_ => {}
if fn_decl.c_variadic {
gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable");
}

visit::walk_fn(self, fn_kind, fn_decl, span);
}

Expand All @@ -2074,9 +2068,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
if block.is_none() {
self.check_abi(sig.header.abi, ti.span);
}
if sig.header.asyncness.node.is_async() {
gate_feature_post!(&self, async_await, ti.span, "async fn is unstable");
}
if sig.decl.c_variadic {
gate_feature_post!(&self, c_variadic, ti.span,
"C-varaidic functions are unstable");
"C-variadic functions are unstable");
}
if sig.header.constness.node == ast::Constness::Const {
gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
Expand Down
10 changes: 10 additions & 0 deletions src/libsyntax/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ pub enum FnKind<'a> {
Closure(&'a Expr),
}

impl<'a> FnKind<'a> {
pub fn header(&self) -> Option<&'a FnHeader> {
match *self {
FnKind::ItemFn(_, header, _, _) => Some(header),
FnKind::Method(_, sig, _, _) => Some(&sig.header),
FnKind::Closure(_) => None,
}
}
}

/// Each method of the Visitor trait is a hook to be potentially
/// overridden. Each method's default implementation recursively visits
/// the substructure of the input via the corresponding `walk` method;
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/feature-gate/feature-gate-c_variadic.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![crate_type="lib"]

pub unsafe extern "C" fn test(_: i32, ap: ...) { }
//~^ C-varaidic functions are unstable
//~^ C-variadic functions are unstable
2 changes: 1 addition & 1 deletion src/test/ui/feature-gate/feature-gate-c_variadic.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0658]: C-varaidic functions are unstable
error[E0658]: C-variadic functions are unstable
--> $DIR/feature-gate-c_variadic.rs:3:1
|
LL | pub unsafe extern "C" fn test(_: i32, ap: ...) { }
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/feature-gates/feature-gate-async-await.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

#![feature(futures_api)]

struct S;

impl S {
async fn foo() {} //~ ERROR async fn is unstable
}

trait T {
async fn foo(); //~ ERROR trait fns cannot be declared `async`
//~^ ERROR async fn is unstable
}

async fn foo() {} //~ ERROR async fn is unstable

fn main() {
Expand Down
32 changes: 28 additions & 4 deletions src/test/ui/feature-gates/feature-gate-async-await.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
error[E0706]: trait fns cannot be declared `async`
--> $DIR/feature-gate-async-await.rs:12:5
|
LL | async fn foo();
| ^^^^^^^^^^^^^^^

error[E0658]: async fn is unstable
--> $DIR/feature-gate-async-await.rs:8:5
|
LL | async fn foo() {}
| ^^^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/50547
= help: add #![feature(async_await)] to the crate attributes to enable

error[E0658]: async fn is unstable
--> $DIR/feature-gate-async-await.rs:12:5
|
LL | async fn foo();
| ^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/50547
= help: add #![feature(async_await)] to the crate attributes to enable

error[E0658]: async fn is unstable
--> $DIR/feature-gate-async-await.rs:5:1
--> $DIR/feature-gate-async-await.rs:16:1
|
LL | async fn foo() {}
| ^^^^^^^^^^^^^^^^^
Expand All @@ -8,7 +32,7 @@ LL | async fn foo() {}
= help: add #![feature(async_await)] to the crate attributes to enable

error[E0658]: async blocks are unstable
--> $DIR/feature-gate-async-await.rs:8:13
--> $DIR/feature-gate-async-await.rs:19:13
|
LL | let _ = async {};
| ^^^^^^^^
Expand All @@ -17,14 +41,14 @@ LL | let _ = async {};
= help: add #![feature(async_await)] to the crate attributes to enable

error[E0658]: async closures are unstable
--> $DIR/feature-gate-async-await.rs:9:13
--> $DIR/feature-gate-async-await.rs:20:13
|
LL | let _ = async || {};
| ^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/50547
= help: add #![feature(async_await)] to the crate attributes to enable

error: aborting due to 3 previous errors
error: aborting due to 6 previous errors

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