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 | |
| 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')
| -rw-r--r-- | src/libsyntax/ast.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 38 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 9 |
3 files changed, 25 insertions, 24 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a5058de2c61..391116d2dbc 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -876,7 +876,6 @@ pub struct FnDecl { pub enum FnStyle { UnsafeFn, // declared with "unsafe fn" NormalFn, // declared with "fn" - ExternFn, // declared with "extern fn" } impl fmt::Show for FnStyle { @@ -884,7 +883,6 @@ impl fmt::Show for FnStyle { match *self { NormalFn => "normal".fmt(f), UnsafeFn => "unsafe".fmt(f), - ExternFn => "extern".fmt(f), } } } 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, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index fb823522612..adaf1364e33 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2372,16 +2372,10 @@ impl<'a> State<'a> { abi: abi::Abi, vis: ast::Visibility) -> IoResult<()> { try!(word(&mut self.s, visibility_qualified(vis, ""))); - + try!(self.print_opt_fn_style(opt_fn_style)); if abi != abi::Rust { try!(self.word_nbsp("extern")); try!(self.word_nbsp(abi.to_str())); - - if opt_fn_style != Some(ast::ExternFn) { - try!(self.print_opt_fn_style(opt_fn_style)); - } - } else { - try!(self.print_opt_fn_style(opt_fn_style)); } word(&mut self.s, "fn") @@ -2391,7 +2385,6 @@ impl<'a> State<'a> { match s { ast::NormalFn => Ok(()), ast::UnsafeFn => self.word_nbsp("unsafe"), - ast::ExternFn => self.word_nbsp("extern") } } |
