Skip to content

Commit

Permalink
Properly feature gate all unstable ABIs
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Jul 18, 2016
1 parent 06ca016 commit 9292c0b
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 73 deletions.
1 change: 1 addition & 0 deletions src/doc/book/closures.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ trait system to overload operators. Calling functions is no different. We have
three separate traits to overload with:

```rust
# #![feature(unboxed_closures)]
# mod foo {
pub trait Fn<Args> : FnMut<Args> {
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
Expand Down
73 changes: 41 additions & 32 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,29 @@ macro_rules! gate_feature_post {
}}
}

impl<'a> PostExpansionVisitor<'a> {
fn check_abi(&self, abi: Abi, span: Span) {
match abi {
Abi::RustIntrinsic =>
gate_feature_post!(&self, intrinsics, span,
"intrinsics are subject to change"),
Abi::PlatformIntrinsic => {
gate_feature_post!(&self, platform_intrinsics, span,
"platform intrinsics are experimental and possibly buggy")
},
Abi::Vectorcall => {
gate_feature_post!(&self, abi_vectorcall, span,
"vectorcall is experimental and subject to change")
}
Abi::RustCall => {
gate_feature_post!(&self, unboxed_closures, span,
"rust-call ABI is subject to change");
}
_ => {}
}
}
}

impl<'a> Visitor for PostExpansionVisitor<'a> {
fn visit_attribute(&mut self, attr: &ast::Attribute) {
if !self.context.cm.span_allows_unstable(attr.span) {
Expand Down Expand Up @@ -831,21 +854,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
across platforms, it is recommended to \
use `#[link(name = \"foo\")]` instead")
}
match foreign_module.abi {
Abi::RustIntrinsic =>
gate_feature_post!(&self, intrinsics, i.span,
"intrinsics are subject to change"),
Abi::PlatformIntrinsic => {
gate_feature_post!(&self, platform_intrinsics, i.span,
"platform intrinsics are experimental \
and possibly buggy")
},
Abi::Vectorcall => {
gate_feature_post!(&self, abi_vectorcall, i.span,
"vectorcall is experimental and subject to change")
}
_ => ()
}
self.check_abi(foreign_module.abi, i.span);
}

ast::ItemKind::Fn(..) => {
Expand Down Expand Up @@ -928,6 +937,16 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
visit::walk_foreign_item(self, i)
}

fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node {
ast::TyKind::BareFn(ref bare_fn_ty) => {
self.check_abi(bare_fn_ty.abi, ty.span);
}
_ => {}
}
visit::walk_ty(self, ty)
}

fn visit_expr(&mut self, e: &ast::Expr) {
match e.node {
ast::ExprKind::Box(_) => {
Expand Down Expand Up @@ -1015,23 +1034,10 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
}

match fn_kind {
FnKind::ItemFn(_, _, _, _, abi, _) if abi == Abi::RustIntrinsic => {
gate_feature_post!(&self, intrinsics,
span,
"intrinsics are subject to change")
}
FnKind::ItemFn(_, _, _, _, abi, _) |
FnKind::Method(_, &ast::MethodSig { abi, .. }, _) => match abi {
Abi::RustCall => {
gate_feature_post!(&self, unboxed_closures, span,
"rust-call ABI is subject to change");
},
Abi::Vectorcall => {
gate_feature_post!(&self, abi_vectorcall, span,
"vectorcall is experimental and subject to change");
},
_ => {}
},
FnKind::Method(_, &ast::MethodSig { abi, .. }, _) => {
self.check_abi(abi, span);
}
_ => {}
}
visit::walk_fn(self, fn_kind, fn_decl, block, span);
Expand All @@ -1044,7 +1050,10 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
ti.span,
"associated constants are experimental")
}
ast::TraitItemKind::Method(ref sig, _) => {
ast::TraitItemKind::Method(ref sig, ref block) => {
if block.is_none() {
self.check_abi(sig.abi, ti.span);
}
if sig.constness == ast::Constness::Const {
gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/E0045.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern "rust-call" { fn foo(x: u8, ...); } //~ ERROR E0045
extern "Rust" { fn foo(x: u8, ...); } //~ ERROR E0045

fn main() {
}
19 changes: 0 additions & 19 deletions src/test/compile-fail/feature-gate-abi-vectorcall.rs

This file was deleted.

60 changes: 60 additions & 0 deletions src/test/compile-fail/feature-gate-abi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Functions
extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change
extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental
extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject to change
extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change

// Methods in trait definition
trait Tr {
extern "rust-intrinsic" fn m1(); //~ ERROR intrinsics are subject to change
extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental
extern "vectorcall" fn m3(); //~ ERROR vectorcall is experimental and subject to change
extern "rust-call" fn m4(); //~ ERROR rust-call ABI is subject to change

extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change
extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental
extern "vectorcall" fn dm3() {} //~ ERROR vectorcall is experimental and subject to change
extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change
}

struct S;

// Methods in trait impl
impl Tr for S {
extern "rust-intrinsic" fn m1() {} //~ ERROR intrinsics are subject to change
extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental
extern "vectorcall" fn m3() {} //~ ERROR vectorcall is experimental and subject to change
extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change
}

// Methods in inherent impl
impl S {
extern "rust-intrinsic" fn im1() {} //~ ERROR intrinsics are subject to change
extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental
extern "vectorcall" fn im3() {} //~ ERROR vectorcall is experimental and subject to change
extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change
}

// Function pointer types
type A1 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to change
type A2 = extern "platform-intrinsic" fn(); //~ ERROR platform intrinsics are experimental
type A3 = extern "vectorcall" fn(); //~ ERROR vectorcall is experimental and subject to change
type A4 = extern "rust-call" fn(); //~ ERROR rust-call ABI is subject to change

// Foreign modules
extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
extern "platform-intrinsic" {} //~ ERROR platform intrinsics are experimental
extern "vectorcall" {} //~ ERROR vectorcall is experimental and subject to change
extern "rust-call" {} //~ ERROR rust-call ABI is subject to change

fn main() {}
21 changes: 0 additions & 21 deletions src/test/compile-fail/feature-gate-rust-call.rs

This file was deleted.

0 comments on commit 9292c0b

Please sign in to comment.