diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-05-06 18:43:56 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-05-06 21:03:59 -0700 |
| commit | 08237cad8d2ce9287aedf99e57384407cc9dc42d (patch) | |
| tree | aca7e5b64833b1216f0a747308533657255e1c1e /src/libsyntax/parse/parser.rs | |
| parent | cf6857b9e9427f14d383ae2924555bedc251fa02 (diff) | |
| download | rust-08237cad8d2ce9287aedf99e57384407cc9dc42d.tar.gz rust-08237cad8d2ce9287aedf99e57384407cc9dc42d.zip | |
rustc: Enable writing "unsafe extern fn() {}"
Previously, the parser would not allow you to simultaneously implement a
function with a different abi as well as being unsafe at the same time. This
extends the parser to allow functions of the form:
unsafe extern fn foo() {
// ...
}
The closure type grammar was also changed to reflect this reversal, types
previously written as "extern unsafe fn()" must now be written as
"unsafe extern fn()". The parser currently has a hack which allows the old
style, but this will go away once a snapshot has landed.
Closes #10025
[breaking-change]
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 11a773a7f09..ca3bad12700 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -27,7 +27,7 @@ use ast::{ExprLit, ExprLoop, ExprMac}; use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary}; use ast::{ExprVec, ExprVstore, ExprVstoreSlice}; -use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, ExternFn, Field, FnDecl}; +use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, Field, FnDecl}; use ast::{ExprVstoreUniq, Once, Many}; use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod}; use ast::{Ident, NormalFn, Inherited, Item, Item_, ItemStatic}; @@ -881,25 +881,29 @@ impl<'a> Parser<'a> { pub fn parse_ty_bare_fn(&mut self) -> Ty_ { /* - [extern "ABI"] [unsafe] fn <'lt> (S) -> T - ^~~~^ ^~~~~~~^ ^~~~^ ^~^ ^ - | | | | | - | | | | Return type - | | | Argument types - | | Lifetimes - | | - | Function Style - ABI - + [unsafe] [extern "ABI"] fn <'lt> (S) -> T + ^~~~^ ^~~~^ ^~~~^ ^~^ ^ + | | | | | + | | | | Return type + | | | Argument types + | | Lifetimes + | ABI + Function Style */ + let fn_style = self.parse_unsafety(); let abi = if self.eat_keyword(keywords::Extern) { self.parse_opt_abi().unwrap_or(abi::C) } else { abi::Rust }; - let fn_style = self.parse_unsafety(); + // NOTE: remove after a stage0 snapshot + let fn_style = match self.parse_unsafety() { + UnsafeFn => UnsafeFn, + NormalFn => fn_style, + }; + self.expect_keyword(keywords::Fn); let (decl, lifetimes) = self.parse_ty_fn_decl(true); return TyBareFn(@BareFnTy { @@ -1245,6 +1249,7 @@ impl<'a> Parser<'a> { self.expect_and(); self.parse_borrowed_pointee() } else if self.is_keyword(keywords::Extern) || + self.is_keyword(keywords::Unsafe) || self.token_is_bare_fn_keyword() { // BARE FUNCTION self.parse_ty_bare_fn() @@ -4551,7 +4556,7 @@ impl<'a> Parser<'a> { // EXTERN FUNCTION ITEM let abi = opt_abi.unwrap_or(abi::C); let (ident, item_, extra_attrs) = - self.parse_item_fn(ExternFn, abi); + self.parse_item_fn(NormalFn, abi); let item = self.mk_item(lo, self.last_span.hi, ident, @@ -4605,9 +4610,14 @@ impl<'a> Parser<'a> { && self.look_ahead(1u, |t| *t != token::LBRACE) { // UNSAFE FUNCTION ITEM self.bump(); + let abi = if self.eat_keyword(keywords::Extern) { + self.parse_opt_abi().unwrap_or(abi::C) + } else { + abi::Rust + }; self.expect_keyword(keywords::Fn); let (ident, item_, extra_attrs) = - self.parse_item_fn(UnsafeFn, abi::Rust); + self.parse_item_fn(UnsafeFn, abi); let item = self.mk_item(lo, self.last_span.hi, ident, |
