diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index f5386b43d5127..1212171d7667d 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -647,6 +647,7 @@ fn ident_start(c: Option) -> bool { (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' + || c == '☢' || (c > '\x7f' && char::is_XID_start(c)) } @@ -657,6 +658,7 @@ fn ident_continue(c: Option) -> bool { || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' + || c == '☢' || (c > '\x7f' && char::is_XID_continue(c)) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6c09fa20510e5..15467b56603d3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -921,8 +921,9 @@ impl<'a> Parser<'a> { return true } - if token::is_keyword(keywords::Unsafe, &self.token) || - token::is_keyword(keywords::Once, &self.token) { + if token::is_keyword(keywords::Unsafe, &self.token) + || token::is_keyword(keywords::Hazard, &self.token) + || token::is_keyword(keywords::Once, &self.token) { return self.look_ahead(1, |t| token::is_keyword(keywords::Fn, t)) } @@ -932,6 +933,7 @@ impl<'a> Parser<'a> { // Is the current token one of the keywords that signals a closure type? pub fn token_is_closure_keyword(&mut self) -> bool { token::is_keyword(keywords::Unsafe, &self.token) || + token::is_keyword(keywords::Hazard, &self.token) || token::is_keyword(keywords::Once, &self.token) } @@ -939,6 +941,7 @@ impl<'a> Parser<'a> { // closure type (with explicit sigil)? pub fn token_is_old_style_closure_keyword(&mut self) -> bool { token::is_keyword(keywords::Unsafe, &self.token) || + token::is_keyword(keywords::Hazard, &self.token) || token::is_keyword(keywords::Once, &self.token) || token::is_keyword(keywords::Fn, &self.token) } @@ -1089,7 +1092,8 @@ impl<'a> Parser<'a> { } pub fn parse_unsafety(&mut self) -> FnStyle { - if self.eat_keyword(keywords::Unsafe) { + if self.eat_keyword(keywords::Unsafe) + || self.eat_keyword(keywords::Hazard) { return UnsafeFn; } else { return NormalFn; @@ -1327,6 +1331,7 @@ impl<'a> Parser<'a> { self.parse_borrowed_pointee() } else if self.is_keyword(keywords::Extern) || self.is_keyword(keywords::Unsafe) || + self.is_keyword(keywords::Hazard) || self.token_is_bare_fn_keyword() { // BARE FUNCTION self.parse_ty_bare_fn() @@ -1868,6 +1873,8 @@ impl<'a> Parser<'a> { return self.parse_match_expr(); } else if self.eat_keyword(keywords::Unsafe) { return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided)); + } else if self.eat_keyword(keywords::Hazard) { + return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided)); } else if self.token == token::LBRACKET { self.bump(); @@ -4306,7 +4313,8 @@ impl<'a> Parser<'a> { // parse safe/unsafe and fn fn parse_fn_style(&mut self) -> FnStyle { if self.eat_keyword(keywords::Fn) { NormalFn } - else if self.eat_keyword(keywords::Unsafe) { + else if self.eat_keyword(keywords::Unsafe) + || self.eat_keyword(keywords::Hazard) { self.expect_keyword(keywords::Fn); UnsafeFn } @@ -4655,7 +4663,7 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return IoviItem(item); } - if self.is_keyword(keywords::Unsafe) + if (self.is_keyword(keywords::Unsafe) || self.is_keyword(keywords::Hazard)) && self.look_ahead(1u, |t| *t != token::LBRACE) { // UNSAFE FUNCTION ITEM self.bump(); @@ -4760,7 +4768,9 @@ impl<'a> Parser<'a> { let item = self.parse_item_foreign_static(visibility, attrs); return IoviForeignItem(item); } - if self.is_keyword(keywords::Fn) || self.is_keyword(keywords::Unsafe) { + if self.is_keyword(keywords::Fn) + || self.is_keyword(keywords::Unsafe) + || self.is_keyword(keywords::Hazard) { // FOREIGN FUNCTION ITEM let item = self.parse_item_foreign_fn(visibility, attrs); return IoviForeignItem(item); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 34f508e42a1eb..6e2a5ac8346e3 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -475,25 +475,26 @@ declare_special_idents_and_keywords! { (33, Trait, "trait"); (34, Type, "type"); (35, Unsafe, "unsafe"); - (36, Use, "use"); - (37, Virtual, "virtual"); - (38, While, "while"); - (39, Continue, "continue"); - (40, Proc, "proc"); - (41, Box, "box"); + (36, Hazard, "☢"); + (37, Use, "use"); + (38, Virtual, "virtual"); + (39, While, "while"); + (40, Continue, "continue"); + (41, Proc, "proc"); + (42, Box, "box"); 'reserved: - (42, Alignof, "alignof"); - (43, Be, "be"); - (44, Const, "const"); - (45, Offsetof, "offsetof"); - (46, Priv, "priv"); - (47, Pure, "pure"); - (48, Sizeof, "sizeof"); - (49, Typeof, "typeof"); - (50, Unsized, "unsized"); - (51, Yield, "yield"); - (52, Do, "do"); + (43, Alignof, "alignof"); + (44, Be, "be"); + (45, Const, "const"); + (46, Offsetof, "offsetof"); + (47, Priv, "priv"); + (48, Pure, "pure"); + (49, Sizeof, "sizeof"); + (50, Typeof, "typeof"); + (51, Unsized, "unsized"); + (52, Yield, "yield"); + (53, Do, "do"); } } diff --git a/src/test/run-pass/hazard.rs b/src/test/run-pass/hazard.rs new file mode 100644 index 0000000000000..de38e4678f99c --- /dev/null +++ b/src/test/run-pass/hazard.rs @@ -0,0 +1,13 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn main() { + ☢ { } +}