diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f47dfeb1d3467..20c0e79f1d8c6 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 0000000000000..0bbfe4c720a5d --- /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 0000000000000..2ba113127b985 --- /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); +}