diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 93fc8b26e7749..e51f178e0fbe7 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -110,7 +110,6 @@ enum Family { UnsafeFn, // u StaticMethod, // F UnsafeStaticMethod, // U - ForeignFn, // e Type, // y ForeignType, // T Mod, // m @@ -134,7 +133,6 @@ fn item_family(item: ebml::Doc) -> Family { 'u' => UnsafeFn, 'F' => StaticMethod, 'U' => UnsafeStaticMethod, - 'e' => ForeignFn, 'y' => Type, 'T' => ForeignType, 'm' => Mod, @@ -339,7 +337,6 @@ fn item_to_def_like(item: ebml::Doc, did: ast::DefId, cnum: ast::CrateNum) Struct => DlDef(ast::DefStruct(did)), UnsafeFn => DlDef(ast::DefFn(did, ast::UnsafeFn)), Fn => DlDef(ast::DefFn(did, ast::NormalFn)), - ForeignFn => DlDef(ast::DefFn(did, ast::ExternFn)), StaticMethod | UnsafeStaticMethod => { let fn_style = if fam == UnsafeStaticMethod { ast::UnsafeFn } else { ast::NormalFn }; diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 214fa3ee04bd9..ef8d5a5004581 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -787,7 +787,6 @@ fn style_fn_family(s: FnStyle) -> char { match s { UnsafeFn => 'u', NormalFn => 'f', - ExternFn => 'e' } } @@ -795,7 +794,6 @@ fn fn_style_static_method_family(s: FnStyle) -> char { match s { UnsafeFn => 'U', NormalFn => 'F', - _ => fail!("extern fn can't be static") } } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index d0501c01aae50..76621cfd09f84 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -441,7 +441,6 @@ fn parse_fn_style(c: char) -> FnStyle { match c { 'u' => UnsafeFn, 'n' => NormalFn, - 'c' => ExternFn, _ => fail!("parse_fn_style: bad fn_style {}", c) } } diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 3a196c5ffab5f..7607542822fba 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -293,7 +293,6 @@ fn enc_fn_style(w: &mut MemWriter, p: FnStyle) { match p { NormalFn => mywrite!(w, "n"), UnsafeFn => mywrite!(w, "u"), - ExternFn => mywrite!(w, "c") } } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index bb7a5d2a24d2e..7dad6473478c1 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -22,6 +22,7 @@ use middle::privacy; use util::nodemap::NodeSet; use collections::HashSet; +use syntax::abi; use syntax::ast; use syntax::ast_map; use syntax::ast_util::{def_id_of_def, is_local}; @@ -250,8 +251,10 @@ impl<'a> ReachableContext<'a> { match *node { ast_map::NodeItem(item) => { match item.node { - ast::ItemFn(_, ast::ExternFn, _, _, _) => { - self.reachable_symbols.insert(search_item); + ast::ItemFn(_, _, abi, _, _) => { + if abi != abi::Rust { + self.reachable_symbols.insert(search_item); + } } _ => {} } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 949937c903723..a5d50f7704e24 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1594,8 +1594,8 @@ impl<'a> Visitor<()> for TransItemVisitor<'a> { pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { let _icx = push_ctxt("trans_item"); match item.node { - ast::ItemFn(decl, fn_style, _abi, ref generics, body) => { - if fn_style == ast::ExternFn { + ast::ItemFn(decl, _fn_style, abi, ref generics, body) => { + if abi != Rust { let llfndecl = get_item_val(ccx, item.id); foreign::trans_rust_fn_with_foreign_abi( ccx, decl, body, item.attrs.as_slice(), llfndecl, item.id); @@ -1939,8 +1939,8 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { } } - ast::ItemFn(_, fn_style, _, _, _) => { - let llfn = if fn_style != ast::ExternFn { + ast::ItemFn(_, _, abi, _, _) => { + let llfn = if abi == Rust { register_fn(ccx, i.span, sym, i.id, ty) } else { foreign::register_rust_fn_with_foreign_abi(ccx, diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index e54a24af96059..307654f1d9699 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -403,6 +403,5 @@ pub fn ast_fn_style_constant(fn_style: ast::FnStyle) -> uint { match fn_style { ast::UnsafeFn => 1u, ast::NormalFn => 2u, - ast::ExternFn => 3u } } diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 32bc7eedf2fcf..42b0321e67d58 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -22,7 +22,7 @@ use middle::typeck::infer::{cres, InferCtxt}; use middle::typeck::infer::{TypeTrace, Subtype}; use middle::typeck::infer::fold_regions_in_sig; use syntax::ast::{Many, Once, MutImmutable, MutMutable}; -use syntax::ast::{ExternFn, NormalFn, UnsafeFn, NodeId}; +use syntax::ast::{NormalFn, UnsafeFn, NodeId}; use syntax::ast::{Onceness, FnStyle}; use collections::HashMap; use util::common::{indenter}; @@ -83,7 +83,6 @@ impl<'f> Combine for Glb<'f> { fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres { match (a, b) { - (ExternFn, _) | (_, ExternFn) => Ok(ExternFn), (NormalFn, _) | (_, NormalFn) => Ok(NormalFn), (UnsafeFn, UnsafeFn) => Ok(UnsafeFn) } diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index d09bbc4253ba9..804c71da73032 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -23,7 +23,7 @@ use middle::typeck::infer::fold_regions_in_sig; use middle::typeck::infer::{TypeTrace, Subtype}; use collections::HashMap; use syntax::ast::{Many, Once, NodeId}; -use syntax::ast::{ExternFn, NormalFn, UnsafeFn}; +use syntax::ast::{NormalFn, UnsafeFn}; use syntax::ast::{Onceness, FnStyle}; use util::ppaux::mt_to_str; @@ -78,8 +78,7 @@ impl<'f> Combine for Lub<'f> { fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres { match (a, b) { (UnsafeFn, _) | (_, UnsafeFn) => Ok(UnsafeFn), - (NormalFn, _) | (_, NormalFn) => Ok(NormalFn), - (ExternFn, ExternFn) => Ok(ExternFn), + (NormalFn, NormalFn) => Ok(NormalFn), } } diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index 4c65a6c148823..c8d6d8f17d61c 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -1200,7 +1200,7 @@ impl Clean for ast::ForeignItem { ForeignFunctionItem(Function { decl: decl.clean(), generics: generics.clean(), - fn_style: ast::ExternFn, + fn_style: ast::NormalFn, }) } ast::ForeignItemStatic(ref ty, mutbl) => { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 1e2f89659cd7d..aef5e8fcb97d1 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -397,10 +397,10 @@ impl fmt::Show for clean::Type { clean::BareFunction(ref decl) => { write!(f.buf, "{}{}fn{}{}", FnStyleSpace(decl.fn_style), - match decl.abi { - ref x if "" == *x => "".to_owned(), - ref x if "\"Rust\"" == *x => "".to_owned(), - ref s => " " + *s + " ", + match decl.abi.as_slice() { + "" => " extern ".to_owned(), + "\"Rust\"" => "".to_owned(), + s => format!(" extern {} ", s) }, decl.generics, decl.decl) @@ -517,7 +517,6 @@ impl fmt::Show for FnStyleSpace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.get() { ast::UnsafeFn => write!(f.buf, "unsafe "), - ast::ExternFn => write!(f.buf, "extern "), ast::NormalFn => Ok(()) } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a5058de2c6135..391116d2dbcd2 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 11a773a7f0930..ca3bad1270059 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 fb82352261214..adaf1364e33bb 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") } } diff --git a/src/test/run-pass/issue-10025.rs b/src/test/run-pass/issue-10025.rs new file mode 100644 index 0000000000000..8f494ea81fcb3 --- /dev/null +++ b/src/test/run-pass/issue-10025.rs @@ -0,0 +1,17 @@ +// 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. + +unsafe extern fn foo() {} +unsafe extern "C" fn bar() {} + +fn main() { + let _a: unsafe extern fn() = foo; + let _a: unsafe extern "C" fn() = foo; +}