1
Fork 0

parser: don't hardcode ABIs into grammar

This commit is contained in:
Mazdak Farrokhzad 2019-10-27 23:14:35 +01:00
parent caf0187141
commit beddf67a4b
20 changed files with 624 additions and 613 deletions

View file

@ -2336,6 +2336,7 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC.
E0657, // `impl Trait` can only capture lifetimes bound at the fn level E0657, // `impl Trait` can only capture lifetimes bound at the fn level
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
E0703, // invalid ABI
// E0707, // multiple elided lifetimes used in arguments of `async fn` // E0707, // multiple elided lifetimes used in arguments of `async fn`
E0708, // `async` non-`move` closures with parameters are not currently E0708, // `async` non-`move` closures with parameters are not currently
// supported // supported

View file

@ -1216,7 +1216,7 @@ impl<'a> LoweringContext<'a> {
ImplTraitContext::disallowed(), ImplTraitContext::disallowed(),
), ),
unsafety: this.lower_unsafety(f.unsafety), unsafety: this.lower_unsafety(f.unsafety),
abi: f.abi, abi: this.lower_abi(f.abi),
decl: this.lower_fn_decl(&f.decl, None, false, None), decl: this.lower_fn_decl(&f.decl, None, false, None),
param_names: this.lower_fn_params_to_names(&f.decl), param_names: this.lower_fn_params_to_names(&f.decl),
})) }))

View file

@ -12,6 +12,7 @@ use crate::hir::def::{Res, DefKind};
use crate::util::nodemap::NodeMap; use crate::util::nodemap::NodeMap;
use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::thin_vec::ThinVec;
use rustc_target::spec::abi;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -735,7 +736,7 @@ impl LoweringContext<'_> {
fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod { fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
hir::ForeignMod { hir::ForeignMod {
abi: fm.abi, abi: self.lower_abi(fm.abi),
items: fm.items items: fm.items
.iter() .iter()
.map(|x| self.lower_foreign_item(x)) .map(|x| self.lower_foreign_item(x))
@ -1291,10 +1292,30 @@ impl LoweringContext<'_> {
unsafety: self.lower_unsafety(h.unsafety), unsafety: self.lower_unsafety(h.unsafety),
asyncness: self.lower_asyncness(h.asyncness.node), asyncness: self.lower_asyncness(h.asyncness.node),
constness: self.lower_constness(h.constness), constness: self.lower_constness(h.constness),
abi: h.abi, abi: self.lower_abi(h.abi),
} }
} }
pub(super) fn lower_abi(&mut self, abi: Abi) -> abi::Abi {
abi::lookup(&abi.symbol.as_str()).unwrap_or_else(|| {
self.error_on_invalid_abi(abi);
abi::Abi::Rust
})
}
fn error_on_invalid_abi(&self, abi: Abi) {
struct_span_err!(
self.sess,
abi.span,
E0703,
"invalid ABI: found `{}`",
abi.symbol
)
.span_label(abi.span, "invalid ABI")
.help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
.emit();
}
pub(super) fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety { pub(super) fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
match u { match u {
Unsafety::Unsafe => hir::Unsafety::Unsafe, Unsafety::Unsafe => hir::Unsafety::Unsafe,

View file

@ -32,7 +32,7 @@ use rls_data::{SigElement, Signature};
use rustc::hir::def::{Res, DefKind}; use rustc::hir::def::{Res, DefKind};
use syntax::ast::{self, NodeId}; use syntax::ast::{self, NodeId};
use syntax::print::pprust; use syntax::print::pprust;
use syntax_pos::sym;
pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option<Signature> { pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option<Signature> {
if !scx.config.signatures { if !scx.config.signatures {
@ -157,6 +157,12 @@ fn text_sig(text: String) -> Signature {
} }
} }
fn push_abi(text: &mut String, abi: ast::Abi) {
if abi.symbol != sym::Rust {
text.push_str(&format!("extern \"{}\" ", abi.symbol));
}
}
impl Sig for ast::Ty { impl Sig for ast::Ty {
fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result { fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
let id = Some(self.id); let id = Some(self.id);
@ -231,11 +237,7 @@ impl Sig for ast::Ty {
if f.unsafety == ast::Unsafety::Unsafe { if f.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe "); text.push_str("unsafe ");
} }
if f.abi != rustc_target::spec::abi::Abi::Rust { push_abi(&mut text, f.abi);
text.push_str("extern");
text.push_str(&f.abi.to_string());
text.push(' ');
}
text.push_str("fn("); text.push_str("fn(");
let mut defs = vec![]; let mut defs = vec![];
@ -385,11 +387,7 @@ impl Sig for ast::Item {
if header.unsafety == ast::Unsafety::Unsafe { if header.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe "); text.push_str("unsafe ");
} }
if header.abi != rustc_target::spec::abi::Abi::Rust { push_abi(&mut text, header.abi);
text.push_str("extern");
text.push_str(&header.abi.to_string());
text.push(' ');
}
text.push_str("fn "); text.push_str("fn ");
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
@ -948,11 +946,7 @@ fn make_method_signature(
if m.header.unsafety == ast::Unsafety::Unsafe { if m.header.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe "); text.push_str("unsafe ");
} }
if m.header.abi != rustc_target::spec::abi::Abi::Rust { push_abi(&mut text, m.header.abi);
text.push_str("extern");
text.push_str(&m.header.abi.to_string());
text.push(' ');
}
text.push_str("fn "); text.push_str("fn ");
let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?; let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?;

View file

@ -38,7 +38,6 @@ use rustc_data_structures::sync::Lrc;
use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::thin_vec::ThinVec;
use rustc_index::vec::Idx; use rustc_index::vec::Idx;
use rustc_serialize::{self, Decoder, Encoder}; use rustc_serialize::{self, Decoder, Encoder};
use rustc_target::spec::abi::Abi;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use rustc_data_structures::static_assert_size; 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. /// A function header.
/// ///
/// All the information between the visibility and the name of the function is /// All the information between the visibility and the name of the function is
@ -2376,7 +2396,7 @@ impl Default for FnHeader {
unsafety: Unsafety::Normal, unsafety: Unsafety::Normal,
asyncness: dummy_spanned(IsAsync::NotAsync), asyncness: dummy_spanned(IsAsync::NotAsync),
constness: dummy_spanned(Constness::NotConst), constness: dummy_spanned(Constness::NotConst),
abi: Abi::Rust, abi: Abi::default(),
} }
} }
} }

View file

@ -540,6 +540,5 @@ equivalent in Rust would be to use macros directly.
E0630, E0630,
E0693, // incorrect `repr(align)` attribute format E0693, // incorrect `repr(align)` attribute format
// E0694, // an unknown tool name found in scoped attributes // E0694, // an unknown tool name found in scoped attributes
E0703, // invalid ABI
E0717, // rustc_promotable without stability attribute E0717, // rustc_promotable without stability attribute
} }

View file

@ -18,7 +18,6 @@ use crate::tokenstream::TokenTree;
use errors::{Applicability, DiagnosticBuilder, Handler}; use errors::{Applicability, DiagnosticBuilder, Handler};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_target::spec::abi::Abi;
use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use log::debug; use log::debug;
@ -192,62 +191,70 @@ macro_rules! gate_feature_post {
} }
impl<'a> PostExpansionVisitor<'a> { impl<'a> PostExpansionVisitor<'a> {
fn check_abi(&self, abi: Abi, span: Span) { fn check_abi(&self, abi: ast::Abi) {
match abi { let ast::Abi { symbol, span } = abi;
Abi::RustIntrinsic => {
match &*symbol.as_str() {
// Stable
"Rust" |
"C" |
"cdecl" |
"stdcall" |
"fastcall" |
"aapcs" |
"win64" |
"sysv64" |
"system" => {}
"rust-intrinsic" => {
gate_feature_post!(&self, intrinsics, span, gate_feature_post!(&self, intrinsics, span,
"intrinsics are subject to change"); "intrinsics are subject to change");
}, },
Abi::PlatformIntrinsic => { "platform-intrinsic" => {
gate_feature_post!(&self, platform_intrinsics, span, gate_feature_post!(&self, platform_intrinsics, span,
"platform intrinsics are experimental and possibly buggy"); "platform intrinsics are experimental and possibly buggy");
}, },
Abi::Vectorcall => { "vectorcall" => {
gate_feature_post!(&self, abi_vectorcall, span, gate_feature_post!(&self, abi_vectorcall, span,
"vectorcall is experimental and subject to change"); "vectorcall is experimental and subject to change");
}, },
Abi::Thiscall => { "thiscall" => {
gate_feature_post!(&self, abi_thiscall, span, gate_feature_post!(&self, abi_thiscall, span,
"thiscall is experimental and subject to change"); "thiscall is experimental and subject to change");
}, },
Abi::RustCall => { "rust-call" => {
gate_feature_post!(&self, unboxed_closures, span, gate_feature_post!(&self, unboxed_closures, span,
"rust-call ABI is subject to change"); "rust-call ABI is subject to change");
}, },
Abi::PtxKernel => { "ptx-kernel" => {
gate_feature_post!(&self, abi_ptx, span, gate_feature_post!(&self, abi_ptx, span,
"PTX ABIs are experimental and subject to change"); "PTX ABIs are experimental and subject to change");
}, },
Abi::Unadjusted => { "unadjusted" => {
gate_feature_post!(&self, abi_unadjusted, span, gate_feature_post!(&self, abi_unadjusted, span,
"unadjusted ABI is an implementation detail and perma-unstable"); "unadjusted ABI is an implementation detail and perma-unstable");
}, },
Abi::Msp430Interrupt => { "msp430-interrupt" => {
gate_feature_post!(&self, abi_msp430_interrupt, span, gate_feature_post!(&self, abi_msp430_interrupt, span,
"msp430-interrupt ABI is experimental and subject to change"); "msp430-interrupt ABI is experimental and subject to change");
}, },
Abi::X86Interrupt => { "x86-interrupt" => {
gate_feature_post!(&self, abi_x86_interrupt, span, gate_feature_post!(&self, abi_x86_interrupt, span,
"x86-interrupt ABI is experimental and subject to change"); "x86-interrupt ABI is experimental and subject to change");
}, },
Abi::AmdGpuKernel => { "amdgpu-kernel" => {
gate_feature_post!(&self, abi_amdgpu_kernel, span, gate_feature_post!(&self, abi_amdgpu_kernel, span,
"amdgpu-kernel ABI is experimental and subject to change"); "amdgpu-kernel ABI is experimental and subject to change");
}, },
Abi::EfiApi => { "efiapi" => {
gate_feature_post!(&self, abi_efiapi, span, gate_feature_post!(&self, abi_efiapi, span,
"efiapi ABI is experimental and subject to change"); "efiapi ABI is experimental and subject to change");
}, },
// Stable abi => {
Abi::Cdecl | self.parse_sess.span_diagnostic.delay_span_bug(
Abi::Stdcall | span,
Abi::Fastcall | &format!("unrecognized ABI not caught in lowering: {}", abi),
Abi::Aapcs | )
Abi::Win64 | }
Abi::SysV64 |
Abi::Rust |
Abi::C |
Abi::System => {}
} }
} }
@ -373,7 +380,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_item(&mut self, i: &'a ast::Item) { fn visit_item(&mut self, i: &'a ast::Item) {
match i.kind { match i.kind {
ast::ItemKind::ForeignMod(ref foreign_module) => { ast::ItemKind::ForeignMod(ref foreign_module) => {
self.check_abi(foreign_module.abi, i.span); self.check_abi(foreign_module.abi);
} }
ast::ItemKind::Fn(..) => { ast::ItemKind::Fn(..) => {
@ -503,7 +510,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_ty(&mut self, ty: &'a ast::Ty) { fn visit_ty(&mut self, ty: &'a ast::Ty) {
match ty.kind { match ty.kind {
ast::TyKind::BareFn(ref bare_fn_ty) => { 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 => { ast::TyKind::Never => {
gate_feature_post!(&self, never_type, ty.span, 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 // Stability of const fn methods are covered in
// `visit_trait_item` and `visit_impl_item` below; this is // `visit_trait_item` and `visit_impl_item` below; this is
// because default methods don't pass through this point. // 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() { if fn_decl.c_variadic() {
@ -631,7 +638,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
match ti.kind { match ti.kind {
ast::TraitItemKind::Method(ref sig, ref block) => { ast::TraitItemKind::Method(ref sig, ref block) => {
if block.is_none() { if block.is_none() {
self.check_abi(sig.header.abi, ti.span); self.check_abi(sig.header.abi);
} }
if sig.decl.c_variadic() { if sig.decl.c_variadic() {
gate_feature_post!(&self, c_variadic, ti.span, gate_feature_post!(&self, c_variadic, ti.span,

View file

@ -12,7 +12,7 @@ mod diagnostics;
use diagnostics::Error; use diagnostics::Error;
use crate::ast::{ 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, IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
}; };
use crate::parse::{PResult, Directory, DirectoryOwnership}; use crate::parse::{PResult, Directory, DirectoryOwnership};
@ -28,7 +28,6 @@ use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
use crate::ThinVec; use crate::ThinVec;
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
use rustc_target::spec::abi::{self, Abi};
use syntax_pos::{Span, BytePos, DUMMY_SP, FileName}; use syntax_pos::{Span, BytePos, DUMMY_SP, FileName};
use log::debug; use log::debug;
@ -1208,48 +1207,27 @@ impl<'a> Parser<'a> {
/// Parses `extern` followed by an optional ABI string, or nothing. /// Parses `extern` followed by an optional ABI string, or nothing.
fn parse_extern_abi(&mut self) -> PResult<'a, Abi> { fn parse_extern_abi(&mut self) -> PResult<'a, Abi> {
if self.eat_keyword(kw::Extern) { Ok(if self.eat_keyword(kw::Extern) {
Ok(self.parse_opt_abi()?.unwrap_or(Abi::C)) let ext_sp = self.prev_span;
self.parse_opt_abi()?.unwrap_or_else(|| Abi::new(sym::C, ext_sp))
} else { } else {
Ok(Abi::Rust) Abi::default()
} })
} }
/// Parses a string as an ABI spec on an extern type or module. Consumes /// Parses a string as an ABI spec on an extern type or module.
/// the `extern` keyword, if one is found.
fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> { fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
match self.token.kind { match self.token.kind {
token::Literal(token::Lit { kind: token::Str, symbol, suffix }) | token::Literal(token::Lit { kind: token::Str, symbol, suffix }) |
token::Literal(token::Lit { kind: token::StrRaw(..), symbol, suffix }) => { token::Literal(token::Lit { kind: token::StrRaw(..), symbol, suffix }) => {
self.expect_no_suffix(self.token.span, "an ABI spec", suffix); self.expect_no_suffix(self.token.span, "an ABI spec", suffix);
self.bump(); self.bump();
match abi::lookup(&symbol.as_str()) { Ok(Some(Abi::new(symbol, self.prev_span)))
Some(abi) => Ok(Some(abi)),
None => {
self.error_on_invalid_abi(symbol);
Ok(None)
}
}
} }
_ => Ok(None), _ => 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. /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
fn ban_async_in_2015(&self, async_span: Span) { fn ban_async_in_2015(&self, async_span: Span) {
if async_span.rust_2015() { if async_span.rust_2015() {

View file

@ -3,7 +3,7 @@ use super::diagnostics::{Error, dummy_arg, ConsumeClosingDelim};
use crate::maybe_whole; use crate::maybe_whole;
use crate::ptr::P; 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::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness}; use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind}; use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
@ -17,7 +17,6 @@ use crate::ThinVec;
use log::debug; use log::debug;
use std::mem; use std::mem;
use rustc_target::spec::abi::Abi;
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, StashKey}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, StashKey};
use syntax_pos::BytePos; use syntax_pos::BytePos;
@ -111,7 +110,7 @@ impl<'a> Parser<'a> {
return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?)); 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) { if self.eat_keyword(kw::Fn) {
// EXTERN FUNCTION ITEM // EXTERN FUNCTION ITEM
@ -120,12 +119,12 @@ impl<'a> Parser<'a> {
unsafety: Unsafety::Normal, unsafety: Unsafety::Normal,
asyncness: respan(fn_span, IsAsync::NotAsync), asyncness: respan(fn_span, IsAsync::NotAsync),
constness: respan(fn_span, Constness::NotConst), constness: respan(fn_span, Constness::NotConst),
abi: opt_abi.unwrap_or(Abi::C), abi,
}; };
return self.parse_item_fn(lo, vis, attrs, header); return self.parse_item_fn(lo, vis, attrs, header);
} else if self.check(&token::OpenDelim(token::Brace)) { } else if self.check(&token::OpenDelim(token::Brace)) {
return Ok(Some( 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, unsafety,
asyncness, asyncness,
constness: respan(fn_span, Constness::NotConst), 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); return self.parse_item_fn(lo, vis, attrs, header);
} }
@ -238,7 +237,7 @@ impl<'a> Parser<'a> {
unsafety: Unsafety::Normal, unsafety: Unsafety::Normal,
asyncness: respan(fn_span, IsAsync::NotAsync), asyncness: respan(fn_span, IsAsync::NotAsync),
constness: respan(fn_span, Constness::NotConst), 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); return self.parse_item_fn(lo, vis, attrs, header);
} }
@ -1115,15 +1114,13 @@ impl<'a> Parser<'a> {
fn parse_item_foreign_mod( fn parse_item_foreign_mod(
&mut self, &mut self,
lo: Span, lo: Span,
opt_abi: Option<Abi>, abi: Abi,
visibility: Visibility, visibility: Visibility,
mut attrs: Vec<Attribute>, mut attrs: Vec<Attribute>,
extern_sp: Span, extern_sp: Span,
) -> PResult<'a, P<Item>> { ) -> PResult<'a, P<Item>> {
self.expect(&token::OpenDelim(token::Brace))?; self.expect(&token::OpenDelim(token::Brace))?;
let abi = opt_abi.unwrap_or(Abi::C);
attrs.extend(self.parse_inner_attributes()?); attrs.extend(self.parse_inner_attributes()?);
let mut foreign_items = vec![]; let mut foreign_items = vec![];
@ -1801,7 +1798,7 @@ impl<'a> Parser<'a> {
) -> PResult<'a, Option<P<Item>>> { ) -> PResult<'a, Option<P<Item>>> {
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
is_self_allowed: false, 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, is_name_required: |_| true,
})?; })?;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; 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 asyncness = respan(self.prev_span, asyncness);
let unsafety = self.parse_unsafety(); let unsafety = self.parse_unsafety();
let (constness, unsafety, abi) = if is_const_fn { 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 { } else {
let abi = self.parse_extern_abi()?; let abi = self.parse_extern_abi()?;
(respan(self.prev_span, Constness::NotConst), unsafety, abi) (respan(self.prev_span, Constness::NotConst), unsafety, abi)

View file

@ -14,7 +14,6 @@ use crate::sess::ParseSess;
use crate::symbol::{kw, sym}; use crate::symbol::{kw, sym};
use crate::tokenstream::{self, TokenStream, TokenTree}; use crate::tokenstream::{self, TokenStream, TokenTree};
use rustc_target::spec::abi::{self, Abi};
use syntax_pos::{self, BytePos}; use syntax_pos::{self, BytePos};
use syntax_pos::{FileName, Span}; use syntax_pos::{FileName, Span};
@ -1230,7 +1229,7 @@ impl<'a> State<'a> {
} }
ast::ItemKind::ForeignMod(ref nmod) => { ast::ItemKind::ForeignMod(ref nmod) => {
self.head("extern"); self.head("extern");
self.word_nbsp(nmod.abi.to_string()); self.print_abi(nmod.abi);
self.bopen(); self.bopen();
self.print_foreign_mod(nmod, &item.attrs); self.print_foreign_mod(nmod, &item.attrs);
self.bclose(item.span); self.bclose(item.span);
@ -2823,7 +2822,7 @@ impl<'a> State<'a> {
} }
crate fn print_ty_fn(&mut self, crate fn print_ty_fn(&mut self,
abi: abi::Abi, abi: ast::Abi,
unsafety: ast::Unsafety, unsafety: ast::Unsafety,
decl: &ast::FnDecl, decl: &ast::FnDecl,
name: Option<ast::Ident>, name: Option<ast::Ident>,
@ -2884,14 +2883,18 @@ impl<'a> State<'a> {
self.print_asyncness(header.asyncness.node); self.print_asyncness(header.asyncness.node);
self.print_unsafety(header.unsafety); self.print_unsafety(header.unsafety);
if header.abi != Abi::Rust { if header.abi.symbol != sym::Rust {
self.word_nbsp("extern"); self.word_nbsp("extern");
self.word_nbsp(header.abi.to_string()); self.print_abi(header.abi);
} }
self.s.word("fn") 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) { crate fn print_unsafety(&mut self, s: ast::Unsafety) {
match s { match s {
ast::Unsafety::Normal => {}, ast::Unsafety::Normal => {},

View file

@ -34,12 +34,7 @@ fn test_fun_to_string() {
assert_eq!( assert_eq!(
fun_to_string( fun_to_string(
&decl, &decl,
ast::FnHeader { ast::FnHeader::default(),
unsafety: ast::Unsafety::Normal,
constness: source_map::dummy_spanned(ast::Constness::NotConst),
asyncness: source_map::dummy_spanned(ast::IsAsync::NotAsync),
abi: Abi::Rust,
},
abba_ident, abba_ident,
&generics &generics
), ),

View file

@ -182,8 +182,7 @@ use std::iter;
use std::vec; use std::vec;
use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::thin_vec::ThinVec;
use rustc_target::spec::abi::Abi; use syntax::ast::{self, Abi, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
use syntax::ast::{VariantData, GenericParamKind, GenericArg}; use syntax::ast::{VariantData, GenericParamKind, GenericArg};
use syntax::attr; use syntax::attr;
use syntax::source_map::respan; use syntax::source_map::respan;
@ -738,7 +737,7 @@ impl<'a> TraitDef<'a> {
self, self,
type_ident, type_ident,
generics, generics,
Abi::Rust, sym::Rust,
explicit_self, explicit_self,
tys, tys,
body) body)
@ -793,7 +792,7 @@ impl<'a> TraitDef<'a> {
self, self,
type_ident, type_ident,
generics, generics,
Abi::Rust, sym::Rust,
explicit_self, explicit_self,
tys, tys,
body) body)
@ -919,7 +918,7 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef<'_>, trait_: &TraitDef<'_>,
type_ident: Ident, type_ident: Ident,
generics: &Generics, generics: &Generics,
abi: Abi, abi: Symbol,
explicit_self: Option<ast::ExplicitSelf>, explicit_self: Option<ast::ExplicitSelf>,
arg_types: Vec<(Ident, P<ast::Ty>)>, arg_types: Vec<(Ident, P<ast::Ty>)>,
body: P<Expr>) body: P<Expr>)
@ -949,23 +948,27 @@ impl<'a> MethodDef<'a> {
ast::Unsafety::Normal ast::Unsafety::Normal
}; };
let trait_lo_sp = trait_.span.shrink_to_lo();
let sig = ast::MethodSig {
header: ast::FnHeader {
unsafety,
abi: Abi::new(abi, trait_lo_sp),
..ast::FnHeader::default()
},
decl: fn_decl,
};
// Create the method. // Create the method.
ast::ImplItem { ast::ImplItem {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
attrs: self.attributes.clone(), attrs: self.attributes.clone(),
generics: fn_generics, generics: fn_generics,
span: trait_.span, span: trait_.span,
vis: respan(trait_.span.shrink_to_lo(), ast::VisibilityKind::Inherited), vis: respan(trait_lo_sp, ast::VisibilityKind::Inherited),
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
ident: method_ident, ident: method_ident,
kind: ast::ImplItemKind::Method(ast::MethodSig { kind: ast::ImplItemKind::Method(sig, body_block),
header: ast::FnHeader {
unsafety, abi,
..ast::FnHeader::default()
},
decl: fn_decl,
},
body_block),
tokens: None, tokens: None,
} }
} }

View file

@ -563,6 +563,7 @@ symbols! {
rust_2018_preview, rust_2018_preview,
rust_begin_unwind, rust_begin_unwind,
rustc, rustc,
Rust,
RustcDecodable, RustcDecodable,
RustcEncodable, RustcEncodable,
rustc_allocator, rustc_allocator,

View file

@ -1,10 +1,8 @@
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gated-feature-in-macro-arg.rs:8:9 --> $DIR/feature-gated-feature-in-macro-arg.rs:8:16
| |
LL | / extern "rust-intrinsic" { LL | extern "rust-intrinsic" {
LL | | fn atomic_fence(); | ^^^^^^^^^^^^^^^^
LL | | }
| |_________^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable

View file

@ -1,8 +1,8 @@
error[E0658]: msp430-interrupt ABI is experimental and subject to change error[E0658]: msp430-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi-msp430-interrupt.rs:4:1 --> $DIR/feature-gate-abi-msp430-interrupt.rs:4:8
| |
LL | extern "msp430-interrupt" fn foo() {} LL | extern "msp430-interrupt" fn foo() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38487 = note: for more information, see https://github.com/rust-lang/rust/issues/38487
= help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,8 @@
error[E0658]: unadjusted ABI is an implementation detail and perma-unstable error[E0658]: unadjusted ABI is an implementation detail and perma-unstable
--> $DIR/feature-gate-abi_unadjusted.rs:1:1 --> $DIR/feature-gate-abi_unadjusted.rs:1:8
| |
LL | / extern "unadjusted" fn foo() { LL | extern "unadjusted" fn foo() {
LL | | | ^^^^^^^^^^^^
LL | | }
| |_^
| |
= help: add `#![feature(abi_unadjusted)]` to the crate attributes to enable = help: add `#![feature(abi_unadjusted)]` to the crate attributes to enable

View file

@ -1,18 +1,16 @@
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gate-intrinsics.rs:1:1 --> $DIR/feature-gate-intrinsics.rs:1:8
| |
LL | / extern "rust-intrinsic" { LL | extern "rust-intrinsic" {
LL | | fn bar(); | ^^^^^^^^^^^^^^^^
LL | | }
| |_^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gate-intrinsics.rs:5:1 --> $DIR/feature-gate-intrinsics.rs:5:8
| |
LL | extern "rust-intrinsic" fn baz() {} LL | extern "rust-intrinsic" fn baz() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable

View file

@ -1,35 +1,35 @@
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:11:5 --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:11:12
| |
LL | extern "rust-call" fn call(self, args: ()) -> () {} LL | extern "rust-call" fn call(self, args: ()) -> () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:5 --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:12
| |
LL | extern "rust-call" fn call_once(self, args: ()) -> () {} LL | extern "rust-call" fn call_once(self, args: ()) -> () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:5 --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:12
| |
LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:5 --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:12
| |
LL | extern "rust-call" fn call_once(&self, args: ()) -> () {} LL | extern "rust-call" fn call_once(&self, args: ()) -> () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable

View file

@ -1,10 +1,8 @@
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-unboxed-closures.rs:9:5 --> $DIR/feature-gate-unboxed-closures.rs:9:12
| |
LL | / extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { LL | extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 {
LL | | a + b | ^^^^^^^^^^^
LL | | }
| |_____^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable