about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-12-01 01:56:52 +0000
committerbors <bors@rust-lang.org>2014-12-01 01:56:52 +0000
commit222a1eb7e80101de182142dc264cdcd81c894b2c (patch)
treece9742d88e232ad03013be79cba45dc87fce638f
parentacad03a420186ee8f0c28626e59eee55664dd0b4 (diff)
parent63553a10adc8b507edee1fce43f868d93628ce34 (diff)
downloadrust-222a1eb7e80101de182142dc264cdcd81c894b2c.tar.gz
rust-222a1eb7e80101de182142dc264cdcd81c894b2c.zip
auto merge of #19418 : P1start/rust/unsafe-extern-trait, r=alexcrichton
Fixes #19398.
-rw-r--r--src/libsyntax/parse/parser.rs15
-rw-r--r--src/test/compile-fail/issue-19398.rs15
-rw-r--r--src/test/compile-fail/removed-syntax-static-fn.rs2
-rw-r--r--src/test/run-pass/issue-19398.rs19
4 files changed, 43 insertions, 8 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 447f2a376e1..c76d9edf635 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1296,13 +1296,14 @@ impl<'a> Parser<'a> {
                 let lo = p.span.lo;
 
                 let vis = p.parse_visibility();
+                let style = p.parse_fn_style();
                 let abi = if p.eat_keyword(keywords::Extern) {
                     p.parse_opt_abi().unwrap_or(abi::C)
                 } else {
                     abi::Rust
                 };
+                p.expect_keyword(keywords::Fn);
 
-                let style = p.parse_fn_style();
                 let ident = p.parse_ident();
                 let mut generics = p.parse_generics();
 
@@ -4458,12 +4459,13 @@ impl<'a> Parser<'a> {
                                                              self.span.hi) };
                 (ast::MethMac(m), self.span.hi, attrs)
             } else {
+                let fn_style = self.parse_fn_style();
                 let abi = if self.eat_keyword(keywords::Extern) {
                     self.parse_opt_abi().unwrap_or(abi::C)
                 } else {
                     abi::Rust
                 };
-                let fn_style = self.parse_fn_style();
+                self.expect_keyword(keywords::Fn);
                 let ident = self.parse_ident();
                 let mut generics = self.parse_generics();
                 let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
@@ -5009,14 +5011,13 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Parse safe/unsafe and fn
+    /// Parse unsafe or not
     fn parse_fn_style(&mut self) -> FnStyle {
-        if self.eat_keyword(keywords::Fn) { NormalFn }
-        else if self.eat_keyword(keywords::Unsafe) {
-            self.expect_keyword(keywords::Fn);
+        if self.eat_keyword(keywords::Unsafe) {
             UnsafeFn
+        } else {
+            NormalFn
         }
-        else { self.unexpected(); }
     }
 
 
diff --git a/src/test/compile-fail/issue-19398.rs b/src/test/compile-fail/issue-19398.rs
new file mode 100644
index 00000000000..3a6d15e0086
--- /dev/null
+++ b/src/test/compile-fail/issue-19398.rs
@@ -0,0 +1,15 @@
+// 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.
+
+trait T {
+    extern "Rust" unsafe fn foo(); //~ ERROR expected `fn`, found `unsafe`
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/removed-syntax-static-fn.rs b/src/test/compile-fail/removed-syntax-static-fn.rs
index f6455608fdc..e3e1cb0f3ca 100644
--- a/src/test/compile-fail/removed-syntax-static-fn.rs
+++ b/src/test/compile-fail/removed-syntax-static-fn.rs
@@ -11,5 +11,5 @@
 struct S;
 
 impl S {
-    static fn f() {} //~ ERROR unexpected token: `static`
+    static fn f() {} //~ ERROR expected `fn`, found `static`
 }
diff --git a/src/test/run-pass/issue-19398.rs b/src/test/run-pass/issue-19398.rs
new file mode 100644
index 00000000000..1196162568a
--- /dev/null
+++ b/src/test/run-pass/issue-19398.rs
@@ -0,0 +1,19 @@
+// 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.
+
+trait T {
+    unsafe extern "Rust" fn foo();
+}
+
+impl T for () {
+    unsafe extern "Rust" fn foo() {}
+}
+
+fn main() {}