Skip to content

Commit

Permalink
Rollup merge of rust-lang#60088 - varkor:async_await-method-feature-g…
Browse files Browse the repository at this point in the history
…ate, r=cramertj

Feature gate async methods

Fixes rust-lang#60069.
  • Loading branch information
Centril authored Apr 18, 2019
2 parents dca6050 + 7548ca6 commit 22d9083
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 42 deletions.
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
10 changes: 10 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,16 @@

#![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`
}

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

fn main() {
Expand Down
35 changes: 30 additions & 5 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:15: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:18:13
|
LL | let _ = async {};
| ^^^^^^^^
Expand All @@ -17,14 +41,15 @@ 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:19: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`.
Some errors occurred: E0658, E0706.
For more information about an error, try `rustc --explain E0658`.

0 comments on commit 22d9083

Please sign in to comment.