about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/book/closures.md1
-rw-r--r--src/libsyntax/feature_gate.rs73
-rw-r--r--src/test/compile-fail/E0045.rs2
-rw-r--r--src/test/compile-fail/feature-gate-abi-vectorcall.rs19
-rw-r--r--src/test/compile-fail/feature-gate-abi.rs60
-rw-r--r--src/test/compile-fail/feature-gate-rust-call.rs21
6 files changed, 103 insertions, 73 deletions
diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md
index 24fcf886ef0..1470eac9829 100644
--- a/src/doc/book/closures.md
+++ b/src/doc/book/closures.md
@@ -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;
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 2ead0f2f20e..29da0fb1a27 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -810,6 +810,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) {
@@ -841,21 +864,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(..) => {
@@ -938,6 +947,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(_) => {
@@ -1025,23 +1044,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);
@@ -1054,7 +1060,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");
                 }
diff --git a/src/test/compile-fail/E0045.rs b/src/test/compile-fail/E0045.rs
index edec911d3c0..2a731596b4b 100644
--- a/src/test/compile-fail/E0045.rs
+++ b/src/test/compile-fail/E0045.rs
@@ -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() {
 }
diff --git a/src/test/compile-fail/feature-gate-abi-vectorcall.rs b/src/test/compile-fail/feature-gate-abi-vectorcall.rs
deleted file mode 100644
index 79f3c8dc776..00000000000
--- a/src/test/compile-fail/feature-gate-abi-vectorcall.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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.
-
-extern "vectorcall" {   //~ ERROR vectorcall is experimental and subject to change
-    fn bar();
-}
-
-extern "vectorcall" fn baz() {  //~ ERROR vectorcall is experimental and subject to change
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/feature-gate-abi.rs b/src/test/compile-fail/feature-gate-abi.rs
new file mode 100644
index 00000000000..0c01f955c06
--- /dev/null
+++ b/src/test/compile-fail/feature-gate-abi.rs
@@ -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() {}
diff --git a/src/test/compile-fail/feature-gate-rust-call.rs b/src/test/compile-fail/feature-gate-rust-call.rs
deleted file mode 100644
index 029a9cad65f..00000000000
--- a/src/test/compile-fail/feature-gate-rust-call.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 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.
-
-extern "rust-call" fn foo() { } //~ ERROR rust-call ABI is subject to change
-
-trait Foo {
-    extern "rust-call" fn foo();
-}
-
-impl Foo for i32 {
-    extern "rust-call" fn foo() { } //~ ERROR rust-call ABI is subject to change
-}
-
-fn main() { }