From 9f74cc5d2db547e54a3cffa2cf9a0001f37ca554 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 2 Apr 2014 01:19:41 -0700 Subject: [PATCH] syntax: Remove AbiSet, use one Abi This change removes the AbiSet from the AST, converting all usage to have just one Abi value. The current scheme selects a relevant ABI given a list of ABIs based on the target architecture and how relevant each ABI is to that architecture. Instead of this mildly complicated scheme, only one ABI will be allowed in abi strings, and pseudo-abis will be created for special cases as necessary. For example the "system" abi exists for stdcall on win32 and C on win64. Closes #10049 --- src/librustc/front/config.rs | 2 +- src/librustc/metadata/creader.rs | 2 +- src/librustc/metadata/encoder.rs | 10 +- src/librustc/metadata/tydecode.rs | 19 +- src/librustc/metadata/tyencode.rs | 11 +- src/librustc/middle/lint.rs | 3 +- src/librustc/middle/trans/base.rs | 14 +- src/librustc/middle/trans/callee.rs | 12 +- src/librustc/middle/trans/foreign.rs | 34 +-- src/librustc/middle/trans/meth.rs | 3 +- src/librustc/middle/trans/monomorphize.rs | 5 +- src/librustc/middle/trans/type_of.rs | 3 +- src/librustc/middle/ty.rs | 12 +- src/librustc/middle/ty_fold.rs | 2 +- src/librustc/middle/typeck/astconv.rs | 14 +- src/librustc/middle/typeck/check/method.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 8 +- src/librustc/middle/typeck/collect.rs | 22 +- src/librustc/middle/typeck/infer/coercion.rs | 3 +- src/librustc/middle/typeck/infer/combine.rs | 8 +- src/librustc/middle/typeck/mod.rs | 4 +- src/librustc/util/ppaux.rs | 18 +- src/librustdoc/clean.rs | 2 +- src/librustdoc/visit_ast.rs | 4 +- src/libsyntax/abi.rs | 274 ++----------------- src/libsyntax/ast.rs | 8 +- src/libsyntax/ast_map.rs | 14 +- src/libsyntax/ext/build.rs | 4 +- src/libsyntax/fold.rs | 4 +- src/libsyntax/parse/mod.rs | 2 +- src/libsyntax/parse/parser.rs | 85 +++--- src/libsyntax/print/pprust.rs | 53 ++-- src/libsyntax/visit.rs | 4 +- 33 files changed, 205 insertions(+), 460 deletions(-) diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index b4861d196e029..cfbe772a165db 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -90,7 +90,7 @@ fn fold_foreign_mod(cx: &mut Context, nm: &ast::ForeignMod) -> ast::ForeignMod { filter_view_item(cx, a).map(|x| cx.fold_view_item(x)) }).collect(); ast::ForeignMod { - abis: nm.abis, + abi: nm.abi, view_items: filtered_view_items, items: filtered_items } diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 36febfc1a09ca..d957850264681 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -187,7 +187,7 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option { fn visit_item(e: &Env, i: &ast::Item) { match i.node { ast::ItemForeignMod(ref fm) => { - if fm.abis.is_rust() || fm.abis.is_intrinsic() { + if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic { return; } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 1da698beb3896..ec6bb7de380f8 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -33,7 +33,7 @@ use std::hash::Hash; use std::io::MemWriter; use std::str; use collections::HashMap; -use syntax::abi::AbiSet; +use syntax::abi; use syntax::ast::*; use syntax::ast; use syntax::ast_map::{PathElem, PathElems}; @@ -1217,7 +1217,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, nitem: &ForeignItem, index: @RefCell> >, path: PathElems, - abi: AbiSet) { + abi: abi::Abi) { index.borrow_mut().push(entry { val: nitem.id as i64, pos: ebml_w.writer.tell().unwrap(), @@ -1231,7 +1231,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, encode_bounds_and_type(ebml_w, ecx, &lookup_item_type(ecx.tcx,local_def(nitem.id))); encode_name(ebml_w, nitem.ident.name); - if abi.is_intrinsic() { + if abi == abi::RustIntrinsic { (ecx.encode_inlined_item)(ecx, ebml_w, IIForeignRef(nitem)); } else { encode_symbol(ecx, ebml_w, nitem.id); @@ -1279,11 +1279,11 @@ fn my_visit_foreign_item(ni: &ForeignItem, let mut ebml_w = unsafe { ebml_w.unsafe_clone() }; - let abis = ecx.tcx.map.get_foreign_abis(ni.id); + let abi = ecx.tcx.map.get_foreign_abi(ni.id); ecx.tcx.map.with_path(ni.id, |path| { encode_info_for_foreign_item(ecx, &mut ebml_w, ni, index, - path, abis); + path, abi); }); } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 7ff36f13b75b9..409957b8625d5 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -20,7 +20,6 @@ use middle::ty; use std::str; use std::uint; -use syntax::abi::AbiSet; use syntax::abi; use syntax::ast; use syntax::ast::*; @@ -460,18 +459,12 @@ fn parse_purity(c: char) -> Purity { } } -fn parse_abi_set(st: &mut PState) -> AbiSet { +fn parse_abi_set(st: &mut PState) -> abi::Abi { assert_eq!(next(st), '['); - let mut abis = AbiSet::empty(); - while peek(st) != ']' { - scan(st, |c| c == ',', |bytes| { - let abi_str = str::from_utf8(bytes).unwrap().to_owned(); - let abi = abi::lookup(abi_str).expect(abi_str); - abis.add(abi); - }); - } - assert_eq!(next(st), ']'); - return abis; + scan(st, |c| c == ']', |bytes| { + let abi_str = str::from_utf8(bytes).unwrap().to_owned(); + abi::lookup(abi_str).expect(abi_str) + }) } fn parse_onceness(c: char) -> ast::Onceness { @@ -505,7 +498,7 @@ fn parse_bare_fn_ty(st: &mut PState, conv: conv_did) -> ty::BareFnTy { let sig = parse_sig(st, |x,y| conv(x,y)); ty::BareFnTy { purity: purity, - abis: abi, + abi: abi, sig: sig } } diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 7e8480e4311a2..4053db72a28cd 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -23,7 +23,7 @@ use std::fmt; use middle::ty::param_ty; use middle::ty; -use syntax::abi::AbiSet; +use syntax::abi::Abi; use syntax::ast; use syntax::ast::*; use syntax::diagnostic::SpanHandler; @@ -341,12 +341,9 @@ fn enc_purity(w: &mut MemWriter, p: Purity) { } } -fn enc_abi_set(w: &mut MemWriter, abis: AbiSet) { +fn enc_abi(w: &mut MemWriter, abi: Abi) { mywrite!(w, "["); - abis.each(|abi| { - mywrite!(w, "{},", abi.name()); - true - }); + mywrite!(w, "{}", abi.name()); mywrite!(w, "]") } @@ -359,7 +356,7 @@ fn enc_onceness(w: &mut MemWriter, o: Onceness) { pub fn enc_bare_fn_ty(w: &mut MemWriter, cx: &ctxt, ft: &ty::BareFnTy) { enc_purity(w, ft.purity); - enc_abi_set(w, ft.abis); + enc_abi(w, ft.abi); enc_fn_sig(w, cx, &ft.sig); } diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 97f5cca1cabb5..da74d0c7729e6 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -59,6 +59,7 @@ use std::u32; use std::u64; use std::u8; use collections::SmallIntMap; +use syntax::abi; use syntax::ast_map; use syntax::ast_util::IdVisitingOperation; use syntax::attr::{AttrMetaMethods, AttributeMethods}; @@ -892,7 +893,7 @@ fn check_item_ctypes(cx: &Context, it: &ast::Item) { } match it.node { - ast::ItemForeignMod(ref nmod) if !nmod.abis.is_intrinsic() => { + ast::ItemForeignMod(ref nmod) if nmod.abi != abi::RustIntrinsic => { for ni in nmod.items.iter() { match ni.node { ast::ForeignItemFn(decl, _) => check_foreign_fn(cx, decl), diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 133634a9e791c..09bbb95fdd04e 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -855,8 +855,8 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val let name = csearch::get_symbol(&ccx.sess().cstore, did); match ty::get(t).sty { ty::ty_bare_fn(ref fn_ty) => { - match fn_ty.abis.for_target(ccx.sess().targ_cfg.os, - ccx.sess().targ_cfg.arch) { + match fn_ty.abi.for_target(ccx.sess().targ_cfg.os, + ccx.sess().targ_cfg.arch) { Some(Rust) | Some(RustIntrinsic) => { get_extern_rust_fn(ccx, fn_ty.sig.inputs.as_slice(), @@ -865,7 +865,7 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val did) } Some(..) | None => { - let c = foreign::llvm_calling_convention(ccx, fn_ty.abis); + let c = foreign::llvm_calling_convention(ccx, fn_ty.abi); let cconv = c.unwrap_or(lib::llvm::CCallConv); let llty = type_of_fn_from_ty(ccx, t); get_extern_fn(&mut *ccx.externs.borrow_mut(), ccx.llmod, @@ -1601,7 +1601,7 @@ 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, purity, _abis, ref generics, body) => { + ast::ItemFn(decl, purity, _abi, ref generics, body) => { if purity == ast::ExternFn { let llfndecl = get_item_val(ccx, item.id); foreign::trans_rust_fn_with_foreign_abi( @@ -1721,7 +1721,7 @@ fn register_fn(ccx: &CrateContext, -> ValueRef { let f = match ty::get(node_type).sty { ty::ty_bare_fn(ref f) => { - assert!(f.abis.is_rust() || f.abis.is_intrinsic()); + assert!(f.abi == Rust || f.abi == RustIntrinsic); f } _ => fail!("expected bare rust fn or an intrinsic") @@ -1997,8 +1997,8 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { match ni.node { ast::ForeignItemFn(..) => { - let abis = ccx.tcx.map.get_foreign_abis(id); - foreign::register_foreign_item_fn(ccx, abis, ni) + let abi = ccx.tcx.map.get_foreign_abi(id); + foreign::register_foreign_item_fn(ccx, abi, ni) } ast::ForeignItemStatic(..) => { foreign::register_static(ccx, ni) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index dae4b2b471b30..13fcaa486f172 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -50,7 +50,7 @@ use util::ppaux::Repr; use middle::trans::type_::Type; use syntax::ast; -use syntax::abi::AbiSet; +use synabi = syntax::abi; use syntax::ast_map; pub struct MethodData { @@ -363,7 +363,7 @@ pub fn trans_fn_ref_with_vtables( match map_node { ast_map::NodeForeignItem(_) => { - tcx.map.get_foreign_abis(def_id.node).is_intrinsic() + tcx.map.get_foreign_abi(def_id.node) == synabi::RustIntrinsic } _ => false } @@ -572,13 +572,11 @@ pub fn trans_call_inner<'a>( }; let (abi, ret_ty) = match ty::get(callee_ty).sty { - ty::ty_bare_fn(ref f) => (f.abis, f.sig.output), - ty::ty_closure(ref f) => (AbiSet::Rust(), f.sig.output), + ty::ty_bare_fn(ref f) => (f.abi, f.sig.output), + ty::ty_closure(ref f) => (synabi::Rust, f.sig.output), _ => fail!("expected bare rust fn or closure in trans_call_inner") }; - let is_rust_fn = - abi.is_rust() || - abi.is_intrinsic(); + let is_rust_fn = abi == synabi::Rust || abi == synabi::RustIntrinsic; // Generate a location to store the result. If the user does // not care about the result, just make a stack slot. diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 158589393efd2..e70d7bf7568a8 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -27,7 +27,7 @@ use middle::ty::FnSig; use middle::ty; use std::cmp; use std::libc::c_uint; -use syntax::abi::{Cdecl, Aapcs, C, AbiSet, Win64}; +use syntax::abi::{Cdecl, Aapcs, C, Win64, Abi}; use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall, System}; use syntax::codemap::Span; use syntax::parse::token::{InternedString, special_idents}; @@ -73,10 +73,10 @@ struct LlvmSignature { // Calls to external functions pub fn llvm_calling_convention(ccx: &CrateContext, - abis: AbiSet) -> Option { + abi: Abi) -> Option { let os = ccx.sess().targ_cfg.os; let arch = ccx.sess().targ_cfg.arch; - abis.for_target(os, arch).map(|abi| { + abi.for_target(os, arch).map(|abi| { match abi { RustIntrinsic => { // Intrinsics are emitted by monomorphic fn @@ -180,27 +180,27 @@ pub fn register_static(ccx: &CrateContext, } } -pub fn register_foreign_item_fn(ccx: &CrateContext, abis: AbiSet, +pub fn register_foreign_item_fn(ccx: &CrateContext, abi: Abi, foreign_item: &ast::ForeignItem) -> ValueRef { /*! * Registers a foreign function found in a library. * Just adds a LLVM global. */ - debug!("register_foreign_item_fn(abis={}, \ + debug!("register_foreign_item_fn(abi={}, \ path={}, \ foreign_item.id={})", - abis.repr(ccx.tcx()), + abi.repr(ccx.tcx()), ccx.tcx.map.path_to_str(foreign_item.id), foreign_item.id); - let cc = match llvm_calling_convention(ccx, abis) { + let cc = match llvm_calling_convention(ccx, abi) { Some(cc) => cc, None => { ccx.sess().span_fatal(foreign_item.span, format!("ABI `{}` has no suitable calling convention \ for target architecture", - abis.user_string(ccx.tcx()))); + abi.user_string(ccx.tcx()))); } }; @@ -263,8 +263,8 @@ pub fn trans_native_call<'a>( ccx.tn.val_to_str(llfn), ccx.tn.val_to_str(llretptr)); - let (fn_abis, fn_sig) = match ty::get(callee_ty).sty { - ty::ty_bare_fn(ref fn_ty) => (fn_ty.abis, fn_ty.sig.clone()), + let (fn_abi, fn_sig) = match ty::get(callee_ty).sty { + ty::ty_bare_fn(ref fn_ty) => (fn_ty.abi, fn_ty.sig.clone()), _ => ccx.sess().bug("trans_native_call called on non-function type") }; let llsig = foreign_signature(ccx, &fn_sig, passed_arg_tys.as_slice()); @@ -354,14 +354,14 @@ pub fn trans_native_call<'a>( llargs_foreign.push(llarg_foreign); } - let cc = match llvm_calling_convention(ccx, fn_abis) { + let cc = match llvm_calling_convention(ccx, fn_abi) { Some(cc) => cc, None => { // FIXME(#8357) We really ought to report a span here ccx.sess().fatal( format!("ABI string `{}` has no suitable ABI \ for target architecture", - fn_abis.user_string(ccx.tcx()))); + fn_abi.user_string(ccx.tcx()))); } }; @@ -435,9 +435,9 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) { for &foreign_item in foreign_mod.items.iter() { match foreign_item.node { ast::ForeignItemFn(..) => { - let abis = foreign_mod.abis; - if !(abis.is_rust() || abis.is_intrinsic()) { - register_foreign_item_fn(ccx, abis, foreign_item); + match foreign_mod.abi { + Rust | RustIntrinsic => {} + abi => { register_foreign_item_fn(ccx, abi, foreign_item); } } } _ => {} @@ -486,7 +486,7 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext, let t = ty::node_id_to_type(ccx.tcx(), node_id); let (cconv, output) = match ty::get(t).sty { ty::ty_bare_fn(ref fn_ty) => { - let c = llvm_calling_convention(ccx, fn_ty.abis); + let c = llvm_calling_convention(ccx, fn_ty.abi); (c.unwrap_or(lib::llvm::CCallConv), fn_ty.sig.output) } _ => fail!("expected bare fn in register_rust_fn_with_foreign_abi") @@ -534,7 +534,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext, // normal Rust function. This will be the type of the wrappee fn. let f = match ty::get(t).sty { ty::ty_bare_fn(ref f) => { - assert!(!f.abis.is_rust() && !f.abis.is_intrinsic()); + assert!(f.abi != Rust && f.abi != RustIntrinsic); f } _ => { diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index a206d42e58999..851f8207cb68b 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -34,6 +34,7 @@ use util::common::indenter; use util::ppaux::Repr; use std::c_str::ToCStr; +use syntax::abi::Rust; use syntax::parse::token; use syntax::{ast, ast_map, visit}; @@ -393,7 +394,7 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>, debug!("(translating trait callee) loading method"); // Replace the self type (&Self or ~Self) with an opaque pointer. let llcallee_ty = match ty::get(callee_ty).sty { - ty::ty_bare_fn(ref f) if f.abis.is_rust() => { + ty::ty_bare_fn(ref f) if f.abi == Rust => { type_of_rust_fn(ccx, true, f.sig.inputs.slice_from(1), f.sig.output) } _ => { diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 179fda7cc4673..6f2dbc182b04f 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -23,6 +23,7 @@ use middle::ty; use middle::typeck; use util::ppaux::Repr; +use syntax::abi; use syntax::ast; use syntax::ast_map; use syntax::ast_util::local_def; @@ -99,7 +100,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, match map_node { ast_map::NodeForeignItem(_) => { - if !ccx.tcx.map.get_foreign_abis(fn_id.node).is_intrinsic() { + if ccx.tcx.map.get_foreign_abi(fn_id.node) != abi::RustIntrinsic { // Foreign externs don't have to be monomorphized. return (get_item_val(ccx, fn_id.node), true); } @@ -150,7 +151,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, let f = match ty::get(mono_ty).sty { ty::ty_bare_fn(ref f) => { - assert!(f.abis.is_rust() || f.abis.is_intrinsic()); + assert!(f.abi == abi::Rust || f.abi == abi::RustIntrinsic); f } _ => fail!("expected bare rust fn or an intrinsic") diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index a78520c8f6bfd..f45ef45720483 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -19,6 +19,7 @@ use util::ppaux::Repr; use middle::trans::type_::Type; +use syntax::abi; use syntax::ast; use syntax::owned_slice::OwnedSlice; @@ -75,7 +76,7 @@ pub fn type_of_fn_from_ty(cx: &CrateContext, fty: ty::t) -> Type { type_of_rust_fn(cx, true, f.sig.inputs.as_slice(), f.sig.output) } ty::ty_bare_fn(ref f) => { - if f.abis.is_rust() || f.abis.is_intrinsic() { + if f.abi == abi::Rust || f.abi == abi::RustIntrinsic { type_of_rust_fn(cx, false, f.sig.inputs.as_slice(), diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index f9296926c748a..85d47424e2b9a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -51,7 +51,7 @@ use syntax::parse::token; use syntax::parse::token::InternedString; use syntax::{ast, ast_map}; use syntax::owned_slice::OwnedSlice; -use syntax::abi::AbiSet; +use syntax::abi; use syntax; use collections::enum_set::{EnumSet, CLike}; @@ -416,8 +416,8 @@ pub fn type_id(t: t) -> uint { get(t).id } #[deriving(Clone, Eq, TotalEq, Hash)] pub struct BareFnTy { pub purity: ast::Purity, - pub abis: AbiSet, - pub sig: FnSig + pub abi: abi::Abi, + pub sig: FnSig, } #[deriving(Clone, Eq, TotalEq, Hash)] @@ -796,7 +796,7 @@ pub enum type_err { terr_mismatch, terr_purity_mismatch(expected_found), terr_onceness_mismatch(expected_found), - terr_abi_mismatch(expected_found), + terr_abi_mismatch(expected_found), terr_mutability, terr_sigil_mismatch(expected_found), terr_box_mutability, @@ -1409,7 +1409,7 @@ pub fn mk_ctor_fn(cx: &ctxt, mk_bare_fn(cx, BareFnTy { purity: ast::ImpureFn, - abis: AbiSet::Rust(), + abi: abi::Rust, sig: FnSig { binder_id: binder_id, inputs: input_args, @@ -4677,7 +4677,7 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 { ty_bare_fn(ref b) => { byte!(14); hash!(b.purity); - hash!(b.abis); + hash!(b.abi); } ty_closure(ref c) => { byte!(15); diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 7eae2ce3d3364..02c4ffe68c1ee 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -48,7 +48,7 @@ pub trait TypeFolder { fty: &ty::BareFnTy) -> ty::BareFnTy { ty::BareFnTy { sig: self.fold_sig(&fty.sig), - abis: fty.abis, + abi: fty.abi, purity: fty.purity } } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 5d2d221a774e0..82be783616888 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -60,7 +60,7 @@ use middle::typeck::rscope::{RegionScope}; use middle::typeck::lookup_def_tcx; use util::ppaux::Repr; -use syntax::abi::AbiSet; +use syntax::abi; use syntax::{ast, ast_util}; use syntax::codemap::Span; use syntax::owned_slice::OwnedSlice; @@ -519,12 +519,12 @@ pub fn ast_ty_to_ty( ty::mk_tup(tcx, flds) } ast::TyBareFn(ref bf) => { - if bf.decl.variadic && !bf.abis.is_c() { + if bf.decl.variadic && bf.abi != abi::C { tcx.sess.span_err(ast_ty.span, "variadic function must have C calling convention"); } ty::mk_bare_fn(tcx, ty_of_bare_fn(this, ast_ty.id, bf.purity, - bf.abis, bf.decl)) + bf.abi, bf.decl)) } ast::TyClosure(ref f) => { if f.sigil == ast::ManagedSigil { @@ -666,20 +666,20 @@ pub fn ty_of_method( untransformed_self_ty: ty::t, explicit_self: ast::ExplicitSelf, decl: &ast::FnDecl) -> ty::BareFnTy { - ty_of_method_or_bare_fn(this, id, purity, AbiSet::Rust(), Some(SelfInfo { + ty_of_method_or_bare_fn(this, id, purity, abi::Rust, Some(SelfInfo { untransformed_self_ty: untransformed_self_ty, explicit_self: explicit_self }), decl) } pub fn ty_of_bare_fn(this: &AC, id: ast::NodeId, - purity: ast::Purity, abi: AbiSet, + purity: ast::Purity, abi: abi::Abi, decl: &ast::FnDecl) -> ty::BareFnTy { ty_of_method_or_bare_fn(this, id, purity, abi, None, decl) } fn ty_of_method_or_bare_fn(this: &AC, id: ast::NodeId, - purity: ast::Purity, abi: AbiSet, + purity: ast::Purity, abi: abi::Abi, opt_self_info: Option, decl: &ast::FnDecl) -> ty::BareFnTy { debug!("ty_of_method_or_bare_fn"); @@ -726,7 +726,7 @@ fn ty_of_method_or_bare_fn(this: &AC, id: ast::NodeId, return ty::BareFnTy { purity: purity, - abis: abi, + abi: abi, sig: ty::FnSig { binder_id: id, inputs: self_and_input_tys, diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 07ebcf7ee9406..dce4e7fb06b94 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -1164,7 +1164,7 @@ impl<'a> LookupContext<'a> { let fty = ty::mk_bare_fn(tcx, ty::BareFnTy { sig: fn_sig, purity: bare_fn_ty.purity, - abis: bare_fn_ty.abis.clone(), + abi: bare_fn_ty.abi.clone(), }); debug!("after replacing bound regions, fty={}", self.ty_to_str(fty)); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 5752a92835883..20ab2b699c2b6 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -120,7 +120,7 @@ use std::mem::replace; use std::result; use std::slice; use std::vec::Vec; -use syntax::abi::AbiSet; +use syntax::abi; use syntax::ast::{Provided, Required}; use syntax::ast; use syntax::ast_util::local_def; @@ -599,7 +599,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) { check_bounds_are_used(ccx, t.span, &generics.ty_params, tpt_ty); } ast::ItemForeignMod(ref m) => { - if m.abis.is_intrinsic() { + if m.abi == abi::RustIntrinsic { for item in m.items.iter() { check_intrinsic_type(ccx, *item); } @@ -612,7 +612,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) { match item.node { ast::ForeignItemFn(ref fn_decl, _) => { - if fn_decl.variadic && !m.abis.is_c() { + if fn_decl.variadic && m.abi != abi::C { ccx.tcx.sess.span_err( item.span, "variadic function must have C calling convention"); } @@ -4224,7 +4224,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { }; let fty = ty::mk_bare_fn(tcx, ty::BareFnTy { purity: ast::UnsafeFn, - abis: AbiSet::Intrinsic(), + abi: abi::RustIntrinsic, sig: FnSig {binder_id: it.id, inputs: inputs, output: output, diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index ca77061539583..274f88ad4c37d 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -48,7 +48,7 @@ use util::ppaux::Repr; use std::rc::Rc; use collections::HashSet; -use syntax::abi::AbiSet; +use syntax::abi; use syntax::ast::{RegionTyParamBound, TraitTyParamBound}; use syntax::ast; use syntax::ast_map; @@ -116,8 +116,8 @@ impl<'a> AstConv for CrateCtxt<'a> { match self.tcx.map.find(id.node) { Some(ast_map::NodeItem(item)) => ty_of_item(self, item), Some(ast_map::NodeForeignItem(foreign_item)) => { - let abis = self.tcx.map.get_foreign_abis(id.node); - ty_of_foreign_item(self, foreign_item, abis) + let abi = self.tcx.map.get_foreign_abi(id.node); + ty_of_foreign_item(self, foreign_item, abi) } x => { self.tcx.sess.bug(format!("unexpected sort of node \ @@ -550,10 +550,10 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt, fn ensure_generics_abi(ccx: &CrateCtxt, span: Span, - abis: AbiSet, + abi: abi::Abi, generics: &ast::Generics) { if generics.ty_params.len() > 0 && - !(abis.is_rust() || abis.is_intrinsic()) { + !(abi == abi::Rust || abi == abi::RustIntrinsic) { ccx.tcx.sess.span_err(span, "foreign functions may not use type parameters"); } @@ -717,9 +717,9 @@ pub fn convert_foreign(ccx: &CrateCtxt, i: &ast::ForeignItem) { // map, and I regard each time that I use it as a personal and // moral failing, but at the moment it seems like the only // convenient way to extract the ABI. - ndm - let abis = ccx.tcx.map.get_foreign_abis(i.id); + let abi = ccx.tcx.map.get_foreign_abi(i.id); - let tpt = ty_of_foreign_item(ccx, i, abis); + let tpt = ty_of_foreign_item(ccx, i, abi); write_ty_to_tcx(ccx.tcx, i.id, tpt.ty); ccx.tcx.tcache.borrow_mut().insert(local_def(i.id), tpt); @@ -891,7 +891,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item) pub fn ty_of_foreign_item(ccx: &CrateCtxt, it: &ast::ForeignItem, - abis: AbiSet) -> ty::ty_param_bounds_and_ty + abi: abi::Abi) -> ty::ty_param_bounds_and_ty { match it.node { ast::ForeignItemFn(fn_decl, ref generics) => { @@ -899,7 +899,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt, fn_decl, local_def(it.id), generics, - abis) + abi) } ast::ForeignItemStatic(t, _) => { ty::ty_param_bounds_and_ty { @@ -1003,7 +1003,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt, decl: &ast::FnDecl, def_id: ast::DefId, ast_generics: &ast::Generics, - abis: AbiSet) + abi: abi::Abi) -> ty::ty_param_bounds_and_ty { for i in decl.inputs.iter() { @@ -1028,7 +1028,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt, let t_fn = ty::mk_bare_fn( ccx.tcx, ty::BareFnTy { - abis: abis, + abi: abi, purity: ast::UnsafeFn, sig: ty::FnSig {binder_id: def_id.node, inputs: input_tys, diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index 5dc55ab4b5c07..dac018fb848a9 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -77,6 +77,7 @@ use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::resolve::try_resolve_tvar_shallow; use util::common::indenter; +use syntax::abi; use syntax::ast::MutImmutable; use syntax::ast; @@ -384,7 +385,7 @@ impl<'f> Coerce<'f> { debug!("coerce_from_bare_fn(a={}, b={})", a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx)); - if !fn_ty_a.abis.is_rust() || fn_ty_a.purity != ast::ImpureFn { + if fn_ty_a.abi != abi::Rust || fn_ty_a.purity != ast::ImpureFn { return self.subtype(a, b); } diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 4a03e32dee824..749c1ee69387c 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -67,7 +67,7 @@ use std::result; use syntax::ast::{Onceness, Purity}; use syntax::ast; use syntax::owned_slice::OwnedSlice; -use syntax::abi::AbiSet; +use syntax::abi; pub trait Combine { fn infcx<'a>(&'a self) -> &'a InferCtxt<'a>; @@ -195,10 +195,10 @@ pub trait Combine { fn bare_fn_tys(&self, a: &ty::BareFnTy, b: &ty::BareFnTy) -> cres { let purity = if_ok!(self.purities(a.purity, b.purity)); - let abi = if_ok!(self.abis(a.abis, b.abis)); + let abi = if_ok!(self.abi(a.abi, b.abi)); let sig = if_ok!(self.fn_sigs(&a.sig, &b.sig)); Ok(ty::BareFnTy {purity: purity, - abis: abi, + abi: abi, sig: sig}) } @@ -248,7 +248,7 @@ pub trait Combine { fn purities(&self, a: Purity, b: Purity) -> cres; - fn abis(&self, a: AbiSet, b: AbiSet) -> cres { + fn abi(&self, a: abi::Abi, b: abi::Abi) -> cres { if a == b { Ok(a) } else { diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index fb82bf9968afc..d635a9bdec41e 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -358,7 +358,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt, } let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy { purity: ast::ImpureFn, - abis: abi::AbiSet::Rust(), + abi: abi::Rust, sig: ty::FnSig { binder_id: main_id, inputs: Vec::new(), @@ -404,7 +404,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt, let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy { purity: ast::ImpureFn, - abis: abi::AbiSet::Rust(), + abi: abi::Rust, sig: ty::FnSig { binder_id: start_id, inputs: vec!( diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0f7de94a92d8c..4a1be783d9d1d 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -23,7 +23,7 @@ use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_unboxed_vec, ty_infer}; use middle::ty; use middle::typeck; -use syntax::abi::AbiSet; +use syntax::abi; use syntax::ast_map; use syntax::codemap::{Span, Pos}; use syntax::parse::token; @@ -253,14 +253,14 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str { } fn bare_fn_to_str(cx: &ctxt, purity: ast::Purity, - abis: AbiSet, + abi: abi::Abi, ident: Option, sig: &ty::FnSig) -> ~str { - let mut s = if abis.is_rust() { + let mut s = if abi == abi::Rust { ~"" } else { - format!("extern {} ", abis.to_str()) + format!("extern {} ", abi.to_str()) }; match purity { @@ -406,7 +406,7 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str { closure_to_str(cx, *f) } ty_bare_fn(ref f) => { - bare_fn_to_str(cx, f.purity, f.abis, None, &f.sig) + bare_fn_to_str(cx, f.purity, f.abi, None, &f.sig) } ty_infer(infer_ty) => infer_ty.to_str(), ty_err => ~"[type error]", @@ -813,9 +813,9 @@ impl Repr for ast::Visibility { impl Repr for ty::BareFnTy { fn repr(&self, tcx: &ctxt) -> ~str { - format!("BareFnTy \\{purity: {:?}, abis: {}, sig: {}\\}", + format!("BareFnTy \\{purity: {:?}, abi: {}, sig: {}\\}", self.purity, - self.abis.to_str(), + self.abi.to_str(), self.sig.repr(tcx)) } } @@ -968,13 +968,13 @@ impl UserString for ast::Ident { } } -impl Repr for AbiSet { +impl Repr for abi::Abi { fn repr(&self, _tcx: &ctxt) -> ~str { self.to_str() } } -impl UserString for AbiSet { +impl UserString for abi::Abi { fn user_string(&self, _tcx: &ctxt) -> ~str { self.to_str() } diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index ff7f7c6e6f4bd..e92aec8e25c7c 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -975,7 +975,7 @@ impl Clean for ast::BareFnTy { type_params: Vec::new(), }, decl: self.decl.clean(), - abi: self.abis.to_str(), + abi: self.abi.to_str(), } } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 78c6940244c39..a6c1ece6400ed 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -11,7 +11,7 @@ //! Rust AST Visitor. Extracts useful information and massages it into a form //! usable for clean -use syntax::abi::AbiSet; +use syntax::abi; use syntax::ast; use syntax::ast_util; use syntax::ast_map; @@ -95,7 +95,7 @@ impl<'a> RustdocVisitor<'a> { } pub fn visit_fn(&mut self, item: &ast::Item, fd: &ast::FnDecl, - purity: &ast::Purity, _abi: &AbiSet, + purity: &ast::Purity, _abi: &abi::Abi, gen: &ast::Generics) -> Function { debug!("Visiting fn"); Function { diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index caded1dc0b845..a40899de931c9 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -9,12 +9,11 @@ // except according to those terms. use std::fmt; -use std::fmt::Show; #[deriving(Eq)] pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, } -#[deriving(Eq, TotalEq, Hash)] +#[deriving(Eq, TotalEq, Hash, Encodable, Decodable, Clone)] pub enum Abi { // NB: This ordering MUST match the AbiDatas array below. // (This is ensured by the test indices_are_correct().) @@ -65,11 +64,6 @@ pub enum AbiArchitecture { Archs(u32) // Multiple architectures (bitset) } -#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] -pub struct AbiSet { - bits: u32 // each bit represents one of the abis below -} - static AbiDatas: &'static [AbiData] = &[ // Platform-specific ABIs AbiData {abi: Cdecl, name: "cdecl", abi_arch: Archs(IntelBits)}, @@ -136,12 +130,20 @@ impl Abi { self.data().name } - pub fn for_target(&self, os: Os, arch: Architecture) -> Abi { - match (*self, os, arch) { + pub fn for_target(&self, os: Os, arch: Architecture) -> Option { + // If this ABI isn't actually for the specified architecture, then we + // short circuit early + match self.data().abi_arch { + Archs(a) if a & arch.bit() == 0 => return None, + Archs(_) | RustArch | AllArch => {} + } + // Transform this ABI as appropriate for the requested os/arch + // combination. + Some(match (*self, os, arch) { (System, OsWin32, X86) => Stdcall, (System, _, _) => C, (me, _, _) => me, - } + }) } } @@ -151,138 +153,9 @@ impl Architecture { } } -impl AbiSet { - pub fn from(abi: Abi) -> AbiSet { - AbiSet { bits: (1 << abi.index()) } - } - - #[inline] - pub fn Rust() -> AbiSet { - AbiSet::from(Rust) - } - - #[inline] - pub fn C() -> AbiSet { - AbiSet::from(C) - } - - #[inline] - pub fn Intrinsic() -> AbiSet { - AbiSet::from(RustIntrinsic) - } - - pub fn default() -> AbiSet { - AbiSet::C() - } - - pub fn empty() -> AbiSet { - AbiSet { bits: 0 } - } - - #[inline] - pub fn is_rust(&self) -> bool { - self.bits == 1 << Rust.index() - } - - #[inline] - pub fn is_c(&self) -> bool { - self.bits == 1 << C.index() - } - - #[inline] - pub fn is_intrinsic(&self) -> bool { - self.bits == 1 << RustIntrinsic.index() - } - - pub fn contains(&self, abi: Abi) -> bool { - (self.bits & (1 << abi.index())) != 0 - } - - pub fn subset_of(&self, other_abi_set: AbiSet) -> bool { - (self.bits & other_abi_set.bits) == self.bits - } - - pub fn add(&mut self, abi: Abi) { - self.bits |= 1 << abi.index(); - } - - pub fn each(&self, op: |abi: Abi| -> bool) -> bool { - each_abi(|abi| !self.contains(abi) || op(abi)) - } - - pub fn is_empty(&self) -> bool { - self.bits == 0 - } - - pub fn for_target(&self, os: Os, arch: Architecture) -> Option { - // NB---Single platform ABIs come first - - let mut res = None; - - self.each(|abi| { - let data = abi.data(); - match data.abi_arch { - Archs(a) if (a & arch.bit()) != 0 => { res = Some(abi); false } - Archs(_) => { true } - RustArch | AllArch => { res = Some(abi); false } - } - }); - - res.map(|r| r.for_target(os, arch)) - } - - pub fn check_valid(&self) -> Option<(Abi, Abi)> { - let mut abis = Vec::new(); - self.each(|abi| { abis.push(abi); true }); - - for (i, abi) in abis.iter().enumerate() { - let data = abi.data(); - for other_abi in abis.slice(0, i).iter() { - let other_data = other_abi.data(); - debug!("abis=({:?},{:?}) datas=({:?},{:?})", - abi, data.abi_arch, - other_abi, other_data.abi_arch); - match (&data.abi_arch, &other_data.abi_arch) { - (&AllArch, &AllArch) => { - // Two cross-architecture ABIs - return Some((*abi, *other_abi)); - } - (_, &RustArch) | - (&RustArch, _) => { - // Cannot combine Rust or Rust-Intrinsic with - // anything else. - return Some((*abi, *other_abi)); - } - (&Archs(is), &Archs(js)) if (is & js) != 0 => { - // Two ABIs for same architecture - return Some((*abi, *other_abi)); - } - _ => {} - } - } - } - - return None; - } -} - impl fmt::Show for Abi { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.data().name.fmt(f) - } -} - -impl fmt::Show for AbiSet { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f.buf, "\"")); - let mut first = true; - self.each(|abi| { - if first { first = false; } - else { let _ = write!(f.buf, " "); } - let _ = write!(f.buf, "{}", abi.data().name); - true - }); - write!(f.buf, "\"") + write!(f.buf, "\"{}\"", self.name()) } } @@ -304,95 +177,6 @@ fn lookup_baz() { assert!(abi.is_none()); } -#[cfg(test)] -fn cannot_combine(n: Abi, m: Abi) { - let mut set = AbiSet::empty(); - set.add(n); - set.add(m); - match set.check_valid() { - Some((a, b)) => { - assert!((n == a && m == b) || - (m == a && n == b)); - } - None => { - fail!("invalid match not detected"); - } - } -} - -#[cfg(test)] -fn can_combine(n: Abi, m: Abi) { - let mut set = AbiSet::empty(); - set.add(n); - set.add(m); - match set.check_valid() { - Some((_, _)) => { - fail!("valid match declared invalid"); - } - None => {} - } -} - -#[test] -fn cannot_combine_cdecl_and_stdcall() { - cannot_combine(Cdecl, Stdcall); -} - -#[test] -fn cannot_combine_c_and_rust() { - cannot_combine(C, Rust); -} - -#[test] -fn cannot_combine_rust_and_cdecl() { - cannot_combine(Rust, Cdecl); -} - -#[test] -fn cannot_combine_rust_intrinsic_and_cdecl() { - cannot_combine(RustIntrinsic, Cdecl); -} - -#[test] -fn can_combine_system_and_cdecl() { - can_combine(System, Cdecl); -} - -#[test] -fn can_combine_c_and_stdcall() { - can_combine(C, Stdcall); -} - -#[test] -fn can_combine_aapcs_and_stdcall() { - can_combine(Aapcs, Stdcall); -} - -#[test] -fn abi_to_str_stdcall_aaps() { - let mut set = AbiSet::empty(); - set.add(Aapcs); - set.add(Stdcall); - assert!(set.to_str() == ~"\"stdcall aapcs\""); -} - -#[test] -fn abi_to_str_c_aaps() { - let mut set = AbiSet::empty(); - set.add(Aapcs); - set.add(C); - debug!("set = {}", set.to_str()); - assert!(set.to_str() == ~"\"aapcs C\""); -} - -#[test] -fn abi_to_str_rust() { - let mut set = AbiSet::empty(); - set.add(Rust); - debug!("set = {}", set.to_str()); - assert!(set.to_str() == ~"\"Rust\""); -} - #[test] fn indices_are_correct() { for (i, abi_data) in AbiDatas.iter().enumerate() { @@ -407,30 +191,14 @@ fn indices_are_correct() { assert_eq!(ArmBits, bits); } -#[cfg(test)] -fn get_arch(abis: &[Abi], os: Os, arch: Architecture) -> Option { - let mut set = AbiSet::empty(); - for &abi in abis.iter() { - set.add(abi); - } - set.for_target(os, arch) -} - -#[test] -fn pick_multiplatform() { - assert_eq!(get_arch([C, Cdecl], OsLinux, X86), Some(Cdecl)); - assert_eq!(get_arch([C, Cdecl], OsLinux, X86_64), Some(Cdecl)); - assert_eq!(get_arch([C, Cdecl], OsLinux, Arm), Some(C)); -} - #[test] fn pick_uniplatform() { - assert_eq!(get_arch([Stdcall], OsLinux, X86), Some(Stdcall)); - assert_eq!(get_arch([Stdcall], OsLinux, Arm), None); - assert_eq!(get_arch([System], OsLinux, X86), Some(C)); - assert_eq!(get_arch([System], OsWin32, X86), Some(Stdcall)); - assert_eq!(get_arch([System], OsWin32, X86_64), Some(C)); - assert_eq!(get_arch([System], OsWin32, Arm), Some(C)); - assert_eq!(get_arch([Stdcall], OsWin32, X86), Some(Stdcall)); - assert_eq!(get_arch([Stdcall], OsWin32, X86_64), Some(Stdcall)); + assert_eq!(Stdcall.for_arch(OsLinux, X86), Some(Stdcall)); + assert_eq!(Stdcall.for_arch(OsLinux, Arm), None); + assert_eq!(System.for_arch(OsLinux, X86), Some(C)); + assert_eq!(System.for_arch(OsWin32, X86), Some(Stdcall)); + assert_eq!(System.for_arch(OsWin32, X86_64), Some(C)); + assert_eq!(System.for_arch(OsWin32, Arm), Some(C)); + assert_eq!(Stdcall.for_arch(OsWin32, X86), Some(Stdcall)); + assert_eq!(Stdcall.for_arch(OsWin32, X86_64), Some(Stdcall)); } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 3a9cdfb56e32a..4612f8e667364 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -11,7 +11,7 @@ // The Rust abstract syntax tree. use codemap::{Span, Spanned, DUMMY_SP}; -use abi::AbiSet; +use abi::Abi; use ast_util; use owned_slice::OwnedSlice; use parse::token::{InternedString, special_idents, str_to_ident}; @@ -807,7 +807,7 @@ pub struct ClosureTy { #[deriving(Eq, TotalEq, Encodable, Decodable, Hash)] pub struct BareFnTy { pub purity: Purity, - pub abis: AbiSet, + pub abi: Abi, pub lifetimes: Vec, pub decl: P } @@ -941,7 +941,7 @@ pub struct Mod { #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] pub struct ForeignMod { - pub abis: AbiSet, + pub abi: Abi, pub view_items: Vec, pub items: Vec<@ForeignItem>, } @@ -1119,7 +1119,7 @@ pub struct Item { #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] pub enum Item_ { ItemStatic(P, Mutability, @Expr), - ItemFn(P, Purity, AbiSet, Generics, P), + ItemFn(P, Purity, Abi, Generics, P), ItemMod(Mod), ItemForeignMod(ForeignMod), ItemTy(P, Generics), diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index f07b0e71c1ce1..e098dcd99fd88 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::AbiSet; +use abi; use ast::*; use ast_util; use codemap::Span; @@ -224,19 +224,19 @@ impl Map { } } - pub fn get_foreign_abis(&self, id: NodeId) -> AbiSet { + pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi { let parent = self.get_parent(id); - let abis = match self.find_entry(parent) { + let abi = match self.find_entry(parent) { Some(EntryItem(_, i)) => match i.node { - ItemForeignMod(ref nm) => Some(nm.abis), + ItemForeignMod(ref nm) => Some(nm.abi), _ => None }, // Wrong but OK, because the only inlined foreign items are intrinsics. - Some(RootInlinedParent(_)) => Some(AbiSet::Intrinsic()), + Some(RootInlinedParent(_)) => Some(abi::RustIntrinsic), _ => None }; - match abis { - Some(abis) => abis, + match abi { + Some(abi) => abi, None => fail!("expected foreign mod or inlined parent, found {}", self.node_to_str(parent)) } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 489af0fc2d477..ef62f0a01f6c1 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::AbiSet; +use abi; use ast::{P, Ident}; use ast; use ast_util; @@ -826,7 +826,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { Vec::new(), ast::ItemFn(self.fn_decl(inputs, output), ast::ImpureFn, - AbiSet::Rust(), + abi::Rust, generics, body)) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 03963219d52c4..06bf892771dc6 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -170,7 +170,7 @@ pub trait Folder { TyBareFn(@BareFnTy { lifetimes: f.lifetimes.iter().map(|l| fold_lifetime(l, self)).collect(), purity: f.purity, - abis: f.abis, + abi: f.abi, decl: self.fold_fn_decl(f.decl) }) } @@ -198,7 +198,7 @@ pub trait Folder { fn fold_foreign_mod(&mut self, nm: &ForeignMod) -> ForeignMod { ast::ForeignMod { - abis: nm.abis, + abi: nm.abi, view_items: nm.view_items .iter() .map(|x| self.fold_view_item(x)) diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 76126e6780a2b..dbb85972774e7 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -657,7 +657,7 @@ mod test { variadic: false }), ast::ImpureFn, - abi::AbiSet::Rust(), + abi::Rust, ast::Generics{ // no idea on either of these: lifetimes: Vec::new(), ty_params: OwnedSlice::empty(), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b3e488a464d9c..2d78bfe5694c1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -11,7 +11,6 @@ #![macro_escape] use abi; -use abi::AbiSet; use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil}; use ast::{BareFnTy, ClosureTy}; use ast::{RegionTyParamBound, TraitTyParamBound}; @@ -873,17 +872,17 @@ impl<'a> Parser<'a> { */ - let abis = if self.eat_keyword(keywords::Extern) { - self.parse_opt_abis().unwrap_or(AbiSet::C()) + let abi = if self.eat_keyword(keywords::Extern) { + self.parse_opt_abi().unwrap_or(abi::C) } else { - AbiSet::Rust() + abi::Rust }; let purity = self.parse_unsafety(); self.expect_keyword(keywords::Fn); let (decl, lifetimes) = self.parse_ty_fn_decl(true); return TyBareFn(@BareFnTy { - abis: abis, + abi: abi, purity: purity, lifetimes: lifetimes, decl: decl @@ -3770,11 +3769,11 @@ impl<'a> Parser<'a> { } // parse an item-position function declaration. - fn parse_item_fn(&mut self, purity: Purity, abis: AbiSet) -> ItemInfo { + fn parse_item_fn(&mut self, purity: Purity, abi: abi::Abi) -> ItemInfo { let (ident, generics) = self.parse_fn_header(); let decl = self.parse_fn_decl(false); let (inner_attrs, body) = self.parse_inner_attrs_and_block(); - (ident, ItemFn(decl, purity, abis, generics, body), Some(inner_attrs)) + (ident, ItemFn(decl, purity, abi, generics, body), Some(inner_attrs)) } // parse a method in a trait impl, starting with `attrs` attributes. @@ -4237,7 +4236,7 @@ impl<'a> Parser<'a> { // at this point, this is essentially a wrapper for // parse_foreign_items. fn parse_foreign_mod_items(&mut self, - abis: AbiSet, + abi: abi::Abi, first_item_attrs: Vec ) -> ForeignMod { let ParsedItemsAndViewItems { @@ -4252,7 +4251,7 @@ impl<'a> Parser<'a> { } assert!(self.token == token::RBRACE); ast::ForeignMod { - abis: abis, + abi: abi, view_items: view_items, items: foreign_items } @@ -4310,17 +4309,17 @@ impl<'a> Parser<'a> { /// extern {} fn parse_item_foreign_mod(&mut self, lo: BytePos, - opt_abis: Option, + opt_abi: Option, visibility: Visibility, attrs: Vec ) -> ItemOrViewItem { self.expect(&token::LBRACE); - let abis = opt_abis.unwrap_or(AbiSet::C()); + let abi = opt_abi.unwrap_or(abi::C); let (inner, next) = self.parse_inner_attrs_and_next(); - let m = self.parse_foreign_mod_items(abis, next); + let m = self.parse_foreign_mod_items(abi, next); self.expect(&token::RBRACE); let item = self.mk_item(lo, @@ -4440,45 +4439,29 @@ impl<'a> Parser<'a> { // Parses a string as an ABI spec on an extern type or module. Consumes // the `extern` keyword, if one is found. - fn parse_opt_abis(&mut self) -> Option { + fn parse_opt_abi(&mut self) -> Option { match self.token { - token::LIT_STR(s) - | token::LIT_STR_RAW(s, _) => { + token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => { self.bump(); let identifier_string = token::get_ident(s); let the_string = identifier_string.get(); - let mut abis = AbiSet::empty(); - for word in the_string.words() { - match abi::lookup(word) { - Some(abi) => { - if abis.contains(abi) { - self.span_err( - self.span, - format!("ABI `{}` appears twice", - word)); - } else { - abis.add(abi); - } - } - - None => { - self.span_err( - self.span, - format!("illegal ABI: \ - expected one of [{}], \ - found `{}`", - abi::all_names().connect(", "), - word)); - } - } - } - Some(abis) + match abi::lookup(the_string) { + Some(abi) => Some(abi), + None => { + self.span_err( + self.span, + format!("illegal ABI: \ + expected one of [{}], \ + found `{}`", + abi::all_names().connect(", "), + the_string)); + None + } + } } - _ => { - None - } - } + _ => None, + } } // parse one of the items or view items allowed by the @@ -4531,13 +4514,13 @@ impl<'a> Parser<'a> { return self.parse_item_extern_crate(lo, visibility, attrs); } - let opt_abis = self.parse_opt_abis(); + let opt_abi = self.parse_opt_abi(); if self.eat_keyword(keywords::Fn) { // EXTERN FUNCTION ITEM - let abis = opt_abis.unwrap_or(AbiSet::C()); + let abi = opt_abi.unwrap_or(abi::C); let (ident, item_, extra_attrs) = - self.parse_item_fn(ExternFn, abis); + self.parse_item_fn(ExternFn, abi); let item = self.mk_item(lo, self.last_span.hi, ident, @@ -4546,7 +4529,7 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return IoviItem(item); } else if self.token == token::LBRACE { - return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs); + return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs); } let token_str = self.this_token_to_str(); @@ -4572,7 +4555,7 @@ impl<'a> Parser<'a> { // FUNCTION ITEM self.bump(); let (ident, item_, extra_attrs) = - self.parse_item_fn(ImpureFn, AbiSet::Rust()); + self.parse_item_fn(ImpureFn, abi::Rust); let item = self.mk_item(lo, self.last_span.hi, ident, @@ -4587,7 +4570,7 @@ impl<'a> Parser<'a> { self.bump(); self.expect_keyword(keywords::Fn); let (ident, item_, extra_attrs) = - self.parse_item_fn(UnsafeFn, AbiSet::Rust()); + self.parse_item_fn(UnsafeFn, abi::Rust); 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 98a3ff3091623..1eee0fb87d6bf 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::AbiSet; +use abi; use ast::{P, RegionTyParamBound, TraitTyParamBound, Required, Provided}; use ast; use ast_util; @@ -190,7 +190,7 @@ pub fn fun_to_str(decl: &ast::FnDecl, purity: ast::Purity, name: ast::Ident, opt_explicit_self: Option, generics: &ast::Generics) -> ~str { to_str(|s| { - try!(s.print_fn(decl, Some(purity), AbiSet::Rust(), + try!(s.print_fn(decl, Some(purity), abi::Rust, name, generics, opt_explicit_self, ast::Inherited)); try!(s.end()); // Close the head box s.end() // Close the outer box @@ -478,7 +478,7 @@ impl<'a> State<'a> { lifetimes: f.lifetimes.clone(), ty_params: OwnedSlice::empty() }; - try!(self.print_ty_fn(Some(f.abis), None, &None, + try!(self.print_ty_fn(Some(f.abi), None, &None, f.purity, ast::Many, f.decl, None, &None, Some(&generics), None)); } @@ -524,7 +524,7 @@ impl<'a> State<'a> { try!(self.print_outer_attributes(item.attrs.as_slice())); match item.node { ast::ForeignItemFn(decl, ref generics) => { - try!(self.print_fn(decl, None, AbiSet::Rust(), item.ident, generics, + try!(self.print_fn(decl, None, abi::Rust, item.ident, generics, None, item.vis)); try!(self.end()); // end head-ibox try!(word(&mut self.s, ";")); @@ -590,7 +590,7 @@ impl<'a> State<'a> { } ast::ItemForeignMod(ref nmod) => { try!(self.head("extern")); - try!(self.word_nbsp(nmod.abis.to_str())); + try!(self.word_nbsp(nmod.abi.to_str())); try!(self.bopen()); try!(self.print_foreign_mod(nmod, item.attrs.as_slice())); try!(self.bclose(item.span)); @@ -883,7 +883,7 @@ impl<'a> State<'a> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(meth.span.lo)); try!(self.print_outer_attributes(meth.attrs.as_slice())); - try!(self.print_fn(meth.decl, Some(meth.purity), AbiSet::Rust(), + try!(self.print_fn(meth.decl, Some(meth.purity), abi::Rust, meth.ident, &meth.generics, Some(meth.explicit_self.node), meth.vis)); try!(word(&mut self.s, " ")); @@ -1717,14 +1717,14 @@ impl<'a> State<'a> { pub fn print_fn(&mut self, decl: &ast::FnDecl, purity: Option, - abis: AbiSet, + abi: abi::Abi, name: ast::Ident, generics: &ast::Generics, opt_explicit_self: Option, vis: ast::Visibility) -> IoResult<()> { try!(self.head("")); - try!(self.print_fn_header_info(opt_explicit_self, purity, abis, - ast::Many, None, vis)); + try!(self.print_fn_header_info(opt_explicit_self, purity, abi, + ast::Many, None, vis)); try!(self.nbsp()); try!(self.print_ident(name)); try!(self.print_generics(generics)); @@ -2016,7 +2016,7 @@ impl<'a> State<'a> { } pub fn print_ty_fn(&mut self, - opt_abis: Option, + opt_abi: Option, opt_sigil: Option, opt_region: &Option, purity: ast::Purity, @@ -2034,14 +2034,14 @@ impl<'a> State<'a> { if opt_sigil == Some(ast::OwnedSigil) && onceness == ast::Once { try!(word(&mut self.s, "proc")); } else if opt_sigil == Some(ast::BorrowedSigil) { - try!(self.print_extern_opt_abis(opt_abis)); + try!(self.print_extern_opt_abi(opt_abi)); for lifetime in opt_region.iter() { try!(self.print_lifetime(lifetime)); } try!(self.print_purity(purity)); try!(self.print_onceness(onceness)); } else { - try!(self.print_opt_abis_and_extern_if_nondefault(opt_abis)); + try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi)); try!(self.print_opt_sigil(opt_sigil)); try!(self.print_opt_lifetime(opt_region)); try!(self.print_purity(purity)); @@ -2303,24 +2303,25 @@ impl<'a> State<'a> { } } - pub fn print_opt_abis_and_extern_if_nondefault(&mut self, - opt_abis: Option) + pub fn print_opt_abi_and_extern_if_nondefault(&mut self, + opt_abi: Option) -> IoResult<()> { - match opt_abis { - Some(abis) if !abis.is_rust() => { + match opt_abi { + Some(abi::Rust) => Ok(()), + Some(abi) => { try!(self.word_nbsp("extern")); - self.word_nbsp(abis.to_str()) + self.word_nbsp(abi.to_str()) } - Some(_) | None => Ok(()) + None => Ok(()) } } - pub fn print_extern_opt_abis(&mut self, - opt_abis: Option) -> IoResult<()> { - match opt_abis { - Some(abis) => { + pub fn print_extern_opt_abi(&mut self, + opt_abi: Option) -> IoResult<()> { + match opt_abi { + Some(abi) => { try!(self.word_nbsp("extern")); - self.word_nbsp(abis.to_str()) + self.word_nbsp(abi.to_str()) } None => Ok(()) } @@ -2339,15 +2340,15 @@ impl<'a> State<'a> { pub fn print_fn_header_info(&mut self, _opt_explicit_self: Option, opt_purity: Option, - abis: AbiSet, + abi: abi::Abi, onceness: ast::Onceness, opt_sigil: Option, vis: ast::Visibility) -> IoResult<()> { try!(word(&mut self.s, visibility_qualified(vis, ""))); - if abis != AbiSet::Rust() { + if abi != abi::Rust { try!(self.word_nbsp("extern")); - try!(self.word_nbsp(abis.to_str())); + try!(self.word_nbsp(abi.to_str())); if opt_purity != Some(ast::ExternFn) { try!(self.print_opt_purity(opt_purity)); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index de3eb1b9b8d6d..eb03bb1f0bbe0 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::AbiSet; +use abi::Abi; use ast::*; use ast; use codemap::Span; @@ -29,7 +29,7 @@ use owned_slice::OwnedSlice; pub enum FnKind<'a> { // fn foo() or extern "Abi" fn foo() - FkItemFn(Ident, &'a Generics, Purity, AbiSet), + FkItemFn(Ident, &'a Generics, Purity, Abi), // fn foo(&self) FkMethod(Ident, &'a Generics, &'a Method),