about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-10-14 10:17:30 +0000
committerbors <bors@rust-lang.org>2015-10-14 10:17:30 +0000
commita668dd2a563796d6ab94a385e5a49a619c53e8ce (patch)
tree726278c05db10bb72cfc71ca388c5f1530d18847
parent294ef5b158601b09e2a3ca49af124c63a9cf9528 (diff)
parent4c88bf2885d91f9aa0c4aeab619542a50a278f33 (diff)
downloadrust-a668dd2a563796d6ab94a385e5a49a619c53e8ce.tar.gz
rust-a668dd2a563796d6ab94a385e5a49a619c53e8ce.zip
Auto merge of #28827 - thepowersgang:unsafe-const-fn-2, r=Aatch
This is the original test implementation, which works according to the tests I wrote, but might need a review.
-rw-r--r--src/libsyntax/parse/parser.rs11
-rw-r--r--src/test/compile-fail/unsafe-const-fn.rs24
-rw-r--r--src/test/run-pass/unsafe-const-fn.rs31
3 files changed, 63 insertions, 3 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 934e4472bdc..b4c052eb181 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -4380,11 +4380,11 @@ impl<'a> Parser<'a> {
     /// - `extern fn`
     /// - etc
     pub fn parse_fn_front_matter(&mut self) -> PResult<(ast::Constness, ast::Unsafety, abi::Abi)> {
+        let unsafety = try!(self.parse_unsafety());
         let is_const_fn = try!(self.eat_keyword(keywords::Const));
         let (constness, unsafety, abi) = if is_const_fn {
-            (Constness::Const, Unsafety::Normal, abi::Rust)
+            (Constness::Const, unsafety, abi::Rust)
         } else {
-            let unsafety = try!(self.parse_unsafety());
             let abi = if try!(self.eat_keyword(keywords::Extern)) {
                 try!(self.parse_opt_abi()).unwrap_or(abi::C)
             } else {
@@ -5378,9 +5378,14 @@ impl<'a> Parser<'a> {
             } else {
                 abi::Rust
             };
+            let constness = if abi == abi::Rust && try!(self.eat_keyword(keywords::Const) ){
+                Constness::Const
+            } else {
+                Constness::NotConst
+            };
             try!(self.expect_keyword(keywords::Fn));
             let (ident, item_, extra_attrs) =
-                try!(self.parse_item_fn(Unsafety::Unsafe, Constness::NotConst, abi));
+                try!(self.parse_item_fn(Unsafety::Unsafe, constness, abi));
             let last_span = self.last_span;
             let item = self.mk_item(lo,
                                     last_span.hi,
diff --git a/src/test/compile-fail/unsafe-const-fn.rs b/src/test/compile-fail/unsafe-const-fn.rs
new file mode 100644
index 00000000000..0bbfe4c720a
--- /dev/null
+++ b/src/test/compile-fail/unsafe-const-fn.rs
@@ -0,0 +1,24 @@
+// Copyright 2015 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.
+
+// A quick test of 'unsafe const fn' functionality
+
+#![feature(const_fn)]
+
+unsafe const fn dummy(v: u32) -> u32 {
+    !v
+}
+
+const VAL: u32 = dummy(0xFFFF); //~ ERROR E0133
+
+fn main() {
+    assert_eq!(VAL, 0xFFFF0000);
+}
+
diff --git a/src/test/run-pass/unsafe-const-fn.rs b/src/test/run-pass/unsafe-const-fn.rs
new file mode 100644
index 00000000000..2ba113127b9
--- /dev/null
+++ b/src/test/run-pass/unsafe-const-fn.rs
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+// A quick test of 'unsafe const fn' functionality
+
+#![feature(const_fn)]
+
+unsafe const fn dummy(v: u32) -> u32 {
+    !v
+}
+
+struct Type;
+impl Type {
+    unsafe const fn new() -> Type {
+        Type
+    }
+}
+
+const VAL: u32 = unsafe { dummy(0xFFFF) };
+const TYPE_INST: Type = unsafe { Type::new() };
+
+fn main() {
+    assert_eq!(VAL, 0xFFFF0000);
+}