From 4c88bf2885d91f9aa0c4aeab619542a50a278f33 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 3 Oct 2015 23:42:22 +0800 Subject: [PATCH] Implement original version of RFC#1245 --- src/libsyntax/parse/parser.rs | 11 ++++++--- src/test/compile-fail/unsafe-const-fn.rs | 24 ++++++++++++++++++ src/test/run-pass/unsafe-const-fn.rs | 31 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 src/test/compile-fail/unsafe-const-fn.rs create mode 100644 src/test/run-pass/unsafe-const-fn.rs diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f47dfeb1d34..20c0e79f1d8 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 { @@ -5399,9 +5399,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 or the MIT license +// , 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 or the MIT license +// , 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); +}