diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-10-27 23:14:35 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-11-07 05:25:31 +0100 |
| commit | beddf67a4b1ce5f1e14a67690644690c4b1bcfaa (patch) | |
| tree | 8c1dc435432fe3002fe9d7928a924e935ef71027 /src/libsyntax | |
| parent | caf018714189db0b15f9f803adfcb4572ab7a988 (diff) | |
| download | rust-beddf67a4b1ce5f1e14a67690644690c4b1bcfaa.tar.gz rust-beddf67a4b1ce5f1e14a67690644690c4b1bcfaa.zip | |
parser: don't hardcode ABIs into grammar
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/error_codes.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate/check.rs | 63 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 38 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/item.rs | 21 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust/tests.rs | 7 |
7 files changed, 83 insertions, 84 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 2392b809150..f761c35cd5c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -38,7 +38,6 @@ use rustc_data_structures::sync::Lrc; use rustc_data_structures::thin_vec::ThinVec; use rustc_index::vec::Idx; use rustc_serialize::{self, Decoder, Encoder}; -use rustc_target::spec::abi::Abi; #[cfg(target_arch = "x86_64")] use rustc_data_structures::static_assert_size; @@ -2358,6 +2357,27 @@ impl Item { } } +/// A reference to an ABI. +/// +/// In AST our notion of an ABI is still syntactic unlike in `rustc_target::spec::abi::Abi`. +#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, PartialEq)] +pub struct Abi { + pub symbol: Symbol, + pub span: Span, +} + +impl Abi { + pub fn new(symbol: Symbol, span: Span) -> Self { + Self { symbol, span } + } +} + +impl Default for Abi { + fn default() -> Self { + Self::new(sym::Rust, DUMMY_SP) + } +} + /// A function header. /// /// All the information between the visibility and the name of the function is @@ -2376,7 +2396,7 @@ impl Default for FnHeader { unsafety: Unsafety::Normal, asyncness: dummy_spanned(IsAsync::NotAsync), constness: dummy_spanned(Constness::NotConst), - abi: Abi::Rust, + abi: Abi::default(), } } } diff --git a/src/libsyntax/error_codes.rs b/src/libsyntax/error_codes.rs index 941df5ea570..c23c8d65a7f 100644 --- a/src/libsyntax/error_codes.rs +++ b/src/libsyntax/error_codes.rs @@ -540,6 +540,5 @@ equivalent in Rust would be to use macros directly. E0630, E0693, // incorrect `repr(align)` attribute format // E0694, // an unknown tool name found in scoped attributes - E0703, // invalid ABI E0717, // rustc_promotable without stability attribute } diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index b7e75ff3a7e..213e9680524 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -18,7 +18,6 @@ use crate::tokenstream::TokenTree; use errors::{Applicability, DiagnosticBuilder, Handler}; use rustc_data_structures::fx::FxHashMap; -use rustc_target::spec::abi::Abi; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use log::debug; @@ -192,62 +191,70 @@ macro_rules! gate_feature_post { } impl<'a> PostExpansionVisitor<'a> { - fn check_abi(&self, abi: Abi, span: Span) { - match abi { - Abi::RustIntrinsic => { + fn check_abi(&self, abi: ast::Abi) { + let ast::Abi { symbol, span } = abi; + + match &*symbol.as_str() { + // Stable + "Rust" | + "C" | + "cdecl" | + "stdcall" | + "fastcall" | + "aapcs" | + "win64" | + "sysv64" | + "system" => {} + "rust-intrinsic" => { gate_feature_post!(&self, intrinsics, span, "intrinsics are subject to change"); }, - Abi::PlatformIntrinsic => { + "platform-intrinsic" => { gate_feature_post!(&self, platform_intrinsics, span, "platform intrinsics are experimental and possibly buggy"); }, - Abi::Vectorcall => { + "vectorcall" => { gate_feature_post!(&self, abi_vectorcall, span, "vectorcall is experimental and subject to change"); }, - Abi::Thiscall => { + "thiscall" => { gate_feature_post!(&self, abi_thiscall, span, "thiscall is experimental and subject to change"); }, - Abi::RustCall => { + "rust-call" => { gate_feature_post!(&self, unboxed_closures, span, "rust-call ABI is subject to change"); }, - Abi::PtxKernel => { + "ptx-kernel" => { gate_feature_post!(&self, abi_ptx, span, "PTX ABIs are experimental and subject to change"); }, - Abi::Unadjusted => { + "unadjusted" => { gate_feature_post!(&self, abi_unadjusted, span, "unadjusted ABI is an implementation detail and perma-unstable"); }, - Abi::Msp430Interrupt => { + "msp430-interrupt" => { gate_feature_post!(&self, abi_msp430_interrupt, span, "msp430-interrupt ABI is experimental and subject to change"); }, - Abi::X86Interrupt => { + "x86-interrupt" => { gate_feature_post!(&self, abi_x86_interrupt, span, "x86-interrupt ABI is experimental and subject to change"); }, - Abi::AmdGpuKernel => { + "amdgpu-kernel" => { gate_feature_post!(&self, abi_amdgpu_kernel, span, "amdgpu-kernel ABI is experimental and subject to change"); }, - Abi::EfiApi => { + "efiapi" => { gate_feature_post!(&self, abi_efiapi, span, "efiapi ABI is experimental and subject to change"); }, - // Stable - Abi::Cdecl | - Abi::Stdcall | - Abi::Fastcall | - Abi::Aapcs | - Abi::Win64 | - Abi::SysV64 | - Abi::Rust | - Abi::C | - Abi::System => {} + abi => { + self.parse_sess.span_diagnostic.delay_span_bug( + span, + &format!("unrecognized ABI not caught in lowering: {}", abi), + ) + } } } @@ -373,7 +380,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_item(&mut self, i: &'a ast::Item) { match i.kind { ast::ItemKind::ForeignMod(ref foreign_module) => { - self.check_abi(foreign_module.abi, i.span); + self.check_abi(foreign_module.abi); } ast::ItemKind::Fn(..) => { @@ -503,7 +510,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_ty(&mut self, ty: &'a ast::Ty) { match ty.kind { ast::TyKind::BareFn(ref bare_fn_ty) => { - self.check_abi(bare_fn_ty.abi, ty.span); + self.check_abi(bare_fn_ty.abi); } ast::TyKind::Never => { gate_feature_post!(&self, never_type, ty.span, @@ -597,7 +604,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { // Stability of const fn methods are covered in // `visit_trait_item` and `visit_impl_item` below; this is // because default methods don't pass through this point. - self.check_abi(header.abi, span); + self.check_abi(header.abi); } if fn_decl.c_variadic() { @@ -631,7 +638,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match ti.kind { ast::TraitItemKind::Method(ref sig, ref block) => { if block.is_none() { - self.check_abi(sig.header.abi, ti.span); + self.check_abi(sig.header.abi); } if sig.decl.c_variadic() { gate_feature_post!(&self, c_variadic, ti.span, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7652c730e51..382c1a517aa 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -12,7 +12,7 @@ mod diagnostics; use diagnostics::Error; use crate::ast::{ - self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident, + self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident, IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety, }; use crate::parse::{PResult, Directory, DirectoryOwnership}; @@ -28,7 +28,6 @@ use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint}; use crate::ThinVec; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError}; -use rustc_target::spec::abi::{self, Abi}; use syntax_pos::{Span, BytePos, DUMMY_SP, FileName}; use log::debug; @@ -1208,48 +1207,27 @@ impl<'a> Parser<'a> { /// Parses `extern` followed by an optional ABI string, or nothing. fn parse_extern_abi(&mut self) -> PResult<'a, Abi> { - if self.eat_keyword(kw::Extern) { - Ok(self.parse_opt_abi()?.unwrap_or(Abi::C)) + Ok(if self.eat_keyword(kw::Extern) { + let ext_sp = self.prev_span; + self.parse_opt_abi()?.unwrap_or_else(|| Abi::new(sym::C, ext_sp)) } else { - Ok(Abi::Rust) - } + Abi::default() + }) } - /// Parses a string as an ABI spec on an extern type or module. Consumes - /// the `extern` keyword, if one is found. + /// Parses a string as an ABI spec on an extern type or module. fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> { match self.token.kind { token::Literal(token::Lit { kind: token::Str, symbol, suffix }) | token::Literal(token::Lit { kind: token::StrRaw(..), symbol, suffix }) => { self.expect_no_suffix(self.token.span, "an ABI spec", suffix); self.bump(); - match abi::lookup(&symbol.as_str()) { - Some(abi) => Ok(Some(abi)), - None => { - self.error_on_invalid_abi(symbol); - Ok(None) - } - } + Ok(Some(Abi::new(symbol, self.prev_span))) } _ => Ok(None), } } - /// Emit an error where `symbol` is an invalid ABI. - fn error_on_invalid_abi(&self, symbol: Symbol) { - let prev_span = self.prev_span; - struct_span_err!( - self.sess.span_diagnostic, - prev_span, - E0703, - "invalid ABI: found `{}`", - symbol - ) - .span_label(prev_span, "invalid ABI") - .help(&format!("valid ABIs: {}", abi::all_names().join(", "))) - .emit(); - } - /// We are parsing `async fn`. If we are on Rust 2015, emit an error. fn ban_async_in_2015(&self, async_span: Span) { if async_span.rust_2015() { diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index cc6235c6fc7..76411e7cf13 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -3,7 +3,7 @@ use super::diagnostics::{Error, dummy_arg, ConsumeClosingDelim}; use crate::maybe_whole; use crate::ptr::P; -use crate::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item}; +use crate::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item}; use crate::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind}; use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness}; use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind}; @@ -17,7 +17,6 @@ use crate::ThinVec; use log::debug; use std::mem; -use rustc_target::spec::abi::Abi; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, StashKey}; use syntax_pos::BytePos; @@ -111,7 +110,7 @@ impl<'a> Parser<'a> { return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?)); } - let opt_abi = self.parse_opt_abi()?; + let abi = self.parse_opt_abi()?.unwrap_or_else(|| Abi::new(sym::C, extern_sp)); if self.eat_keyword(kw::Fn) { // EXTERN FUNCTION ITEM @@ -120,12 +119,12 @@ impl<'a> Parser<'a> { unsafety: Unsafety::Normal, asyncness: respan(fn_span, IsAsync::NotAsync), constness: respan(fn_span, Constness::NotConst), - abi: opt_abi.unwrap_or(Abi::C), + abi, }; return self.parse_item_fn(lo, vis, attrs, header); } else if self.check(&token::OpenDelim(token::Brace)) { return Ok(Some( - self.parse_item_foreign_mod(lo, opt_abi, vis, attrs, extern_sp)?, + self.parse_item_foreign_mod(lo, abi, vis, attrs, extern_sp)?, )); } @@ -201,7 +200,7 @@ impl<'a> Parser<'a> { unsafety, asyncness, constness: respan(fn_span, Constness::NotConst), - abi: Abi::Rust, + abi: Abi::new(sym::Rust, fn_span), }; return self.parse_item_fn(lo, vis, attrs, header); } @@ -238,7 +237,7 @@ impl<'a> Parser<'a> { unsafety: Unsafety::Normal, asyncness: respan(fn_span, IsAsync::NotAsync), constness: respan(fn_span, Constness::NotConst), - abi: Abi::Rust, + abi: Abi::new(sym::Rust, fn_span), }; return self.parse_item_fn(lo, vis, attrs, header); } @@ -1115,15 +1114,13 @@ impl<'a> Parser<'a> { fn parse_item_foreign_mod( &mut self, lo: Span, - opt_abi: Option<Abi>, + abi: Abi, visibility: Visibility, mut attrs: Vec<Attribute>, extern_sp: Span, ) -> PResult<'a, P<Item>> { self.expect(&token::OpenDelim(token::Brace))?; - let abi = opt_abi.unwrap_or(Abi::C); - attrs.extend(self.parse_inner_attributes()?); let mut foreign_items = vec![]; @@ -1801,7 +1798,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, Option<P<Item>>> { let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { is_self_allowed: false, - allow_c_variadic: header.abi == Abi::C && header.unsafety == Unsafety::Unsafe, + allow_c_variadic: header.abi.symbol == sym::C && header.unsafety == Unsafety::Unsafe, is_name_required: |_| true, })?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; @@ -1930,7 +1927,7 @@ impl<'a> Parser<'a> { let asyncness = respan(self.prev_span, asyncness); let unsafety = self.parse_unsafety(); let (constness, unsafety, abi) = if is_const_fn { - (respan(const_span, Constness::Const), unsafety, Abi::Rust) + (respan(const_span, Constness::Const), unsafety, Abi::default()) } else { let abi = self.parse_extern_abi()?; (respan(self.prev_span, Constness::NotConst), unsafety, abi) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c8afe8a1ff4..1d59c13a9d0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -14,7 +14,6 @@ use crate::sess::ParseSess; use crate::symbol::{kw, sym}; use crate::tokenstream::{self, TokenStream, TokenTree}; -use rustc_target::spec::abi::{self, Abi}; use syntax_pos::{self, BytePos}; use syntax_pos::{FileName, Span}; @@ -1230,7 +1229,7 @@ impl<'a> State<'a> { } ast::ItemKind::ForeignMod(ref nmod) => { self.head("extern"); - self.word_nbsp(nmod.abi.to_string()); + self.print_abi(nmod.abi); self.bopen(); self.print_foreign_mod(nmod, &item.attrs); self.bclose(item.span); @@ -2823,7 +2822,7 @@ impl<'a> State<'a> { } crate fn print_ty_fn(&mut self, - abi: abi::Abi, + abi: ast::Abi, unsafety: ast::Unsafety, decl: &ast::FnDecl, name: Option<ast::Ident>, @@ -2884,14 +2883,18 @@ impl<'a> State<'a> { self.print_asyncness(header.asyncness.node); self.print_unsafety(header.unsafety); - if header.abi != Abi::Rust { + if header.abi.symbol != sym::Rust { self.word_nbsp("extern"); - self.word_nbsp(header.abi.to_string()); + self.print_abi(header.abi); } self.s.word("fn") } + fn print_abi(&mut self, abi: ast::Abi) { + self.word_nbsp(format!("\"{}\"", abi.symbol)); + } + crate fn print_unsafety(&mut self, s: ast::Unsafety) { match s { ast::Unsafety::Normal => {}, diff --git a/src/libsyntax/print/pprust/tests.rs b/src/libsyntax/print/pprust/tests.rs index faa70edbfa2..2c6dd0fb1c6 100644 --- a/src/libsyntax/print/pprust/tests.rs +++ b/src/libsyntax/print/pprust/tests.rs @@ -34,12 +34,7 @@ fn test_fun_to_string() { assert_eq!( fun_to_string( &decl, - ast::FnHeader { - unsafety: ast::Unsafety::Normal, - constness: source_map::dummy_spanned(ast::Constness::NotConst), - asyncness: source_map::dummy_spanned(ast::IsAsync::NotAsync), - abi: Abi::Rust, - }, + ast::FnHeader::default(), abba_ident, &generics ), |
