Skip to content

Commit 39c5b07

Browse files
committed
parser: don't hardcode ABIs into grammar
1 parent eb5ef81 commit 39c5b07

20 files changed

+296
-285
lines changed

src/librustc/error_codes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2336,6 +2336,7 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC.
23362336
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
23372337
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
23382338
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
2339+
E0703, // invalid ABI
23392340
// E0707, // multiple elided lifetimes used in arguments of `async fn`
23402341
E0708, // `async` non-`move` closures with parameters are not currently
23412342
// supported

src/librustc/hir/lowering.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,7 @@ impl<'a> LoweringContext<'a> {
12101210
ImplTraitContext::disallowed(),
12111211
),
12121212
unsafety: this.lower_unsafety(f.unsafety),
1213-
abi: f.abi,
1213+
abi: this.lower_abi(f.abi),
12141214
decl: this.lower_fn_decl(&f.decl, None, false, None),
12151215
param_names: this.lower_fn_params_to_names(&f.decl),
12161216
}))

src/librustc/hir/lowering/item.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::hir::def::{Res, DefKind};
1212
use crate::util::nodemap::NodeMap;
1313

1414
use rustc_data_structures::thin_vec::ThinVec;
15+
use rustc_target::spec::abi;
1516

1617
use std::collections::BTreeSet;
1718
use smallvec::SmallVec;
@@ -742,7 +743,7 @@ impl LoweringContext<'_> {
742743

743744
fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
744745
hir::ForeignMod {
745-
abi: fm.abi,
746+
abi: self.lower_abi(fm.abi),
746747
items: fm.items
747748
.iter()
748749
.map(|x| self.lower_foreign_item(x))
@@ -1298,10 +1299,30 @@ impl LoweringContext<'_> {
12981299
unsafety: self.lower_unsafety(h.unsafety),
12991300
asyncness: self.lower_asyncness(h.asyncness.node),
13001301
constness: self.lower_constness(h.constness),
1301-
abi: h.abi,
1302+
abi: self.lower_abi(h.abi),
13021303
}
13031304
}
13041305

1306+
pub(super) fn lower_abi(&mut self, abi: Abi) -> abi::Abi {
1307+
abi::lookup(&abi.symbol.as_str()).unwrap_or_else(|| {
1308+
self.error_on_invalid_abi(abi);
1309+
abi::Abi::Rust
1310+
})
1311+
}
1312+
1313+
fn error_on_invalid_abi(&self, abi: Abi) {
1314+
struct_span_err!(
1315+
self.sess,
1316+
abi.span,
1317+
E0703,
1318+
"invalid ABI: found `{}`",
1319+
abi.symbol
1320+
)
1321+
.span_label(abi.span, "invalid ABI")
1322+
.help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
1323+
.emit();
1324+
}
1325+
13051326
pub(super) fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
13061327
match u {
13071328
Unsafety::Unsafe => hir::Unsafety::Unsafe,

src/librustc_save_analysis/sig.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use rls_data::{SigElement, Signature};
3232
use rustc::hir::def::{Res, DefKind};
3333
use syntax::ast::{self, NodeId};
3434
use syntax::print::pprust;
35-
35+
use syntax_pos::sym;
3636

3737
pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option<Signature> {
3838
if !scx.config.signatures {
@@ -157,6 +157,12 @@ fn text_sig(text: String) -> Signature {
157157
}
158158
}
159159

160+
fn push_abi(text: &mut String, abi: ast::Abi) {
161+
if abi.symbol != sym::Rust {
162+
text.push_str(&format!("extern \"{}\" ", abi.symbol));
163+
}
164+
}
165+
160166
impl Sig for ast::Ty {
161167
fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
162168
let id = Some(self.id);
@@ -231,11 +237,7 @@ impl Sig for ast::Ty {
231237
if f.unsafety == ast::Unsafety::Unsafe {
232238
text.push_str("unsafe ");
233239
}
234-
if f.abi != rustc_target::spec::abi::Abi::Rust {
235-
text.push_str("extern");
236-
text.push_str(&f.abi.to_string());
237-
text.push(' ');
238-
}
240+
push_abi(&mut text, f.abi);
239241
text.push_str("fn(");
240242

241243
let mut defs = vec![];
@@ -385,11 +387,7 @@ impl Sig for ast::Item {
385387
if header.unsafety == ast::Unsafety::Unsafe {
386388
text.push_str("unsafe ");
387389
}
388-
if header.abi != rustc_target::spec::abi::Abi::Rust {
389-
text.push_str("extern");
390-
text.push_str(&header.abi.to_string());
391-
text.push(' ');
392-
}
390+
push_abi(&mut text, header.abi);
393391
text.push_str("fn ");
394392

395393
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
@@ -948,11 +946,7 @@ fn make_method_signature(
948946
if m.header.unsafety == ast::Unsafety::Unsafe {
949947
text.push_str("unsafe ");
950948
}
951-
if m.header.abi != rustc_target::spec::abi::Abi::Rust {
952-
text.push_str("extern");
953-
text.push_str(&m.header.abi.to_string());
954-
text.push(' ');
955-
}
949+
push_abi(&mut text, m.header.abi);
956950
text.push_str("fn ");
957951

958952
let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?;

src/libsyntax/ast.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ use rustc_data_structures::sync::Lrc;
3838
use rustc_data_structures::thin_vec::ThinVec;
3939
use rustc_index::vec::Idx;
4040
use rustc_serialize::{self, Decoder, Encoder};
41-
use rustc_target::spec::abi::Abi;
4241

4342
#[cfg(target_arch = "x86_64")]
4443
use rustc_data_structures::static_assert_size;
@@ -2351,6 +2350,27 @@ impl Item {
23512350
}
23522351
}
23532352

2353+
/// A reference to an ABI.
2354+
///
2355+
/// In AST our notion of an ABI is still syntactic unlike in `rustc_target::spec::abi::Abi`.
2356+
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, PartialEq)]
2357+
pub struct Abi {
2358+
pub symbol: Symbol,
2359+
pub span: Span,
2360+
}
2361+
2362+
impl Abi {
2363+
pub fn new(symbol: Symbol, span: Span) -> Self {
2364+
Self { symbol, span }
2365+
}
2366+
}
2367+
2368+
impl Default for Abi {
2369+
fn default() -> Self {
2370+
Self::new(sym::Rust, DUMMY_SP)
2371+
}
2372+
}
2373+
23542374
/// A function header.
23552375
///
23562376
/// All the information between the visibility and the name of the function is
@@ -2369,7 +2389,7 @@ impl Default for FnHeader {
23692389
unsafety: Unsafety::Normal,
23702390
asyncness: dummy_spanned(IsAsync::NotAsync),
23712391
constness: dummy_spanned(Constness::NotConst),
2372-
abi: Abi::Rust,
2392+
abi: Abi::default(),
23732393
}
23742394
}
23752395
}

src/libsyntax/error_codes.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,5 @@ features in the `-Z allow_features` flag.
527527
E0630,
528528
E0693, // incorrect `repr(align)` attribute format
529529
// E0694, // an unknown tool name found in scoped attributes
530-
E0703, // invalid ABI
531530
E0717, // rustc_promotable without stability attribute
532531
}

src/libsyntax/feature_gate/check.rs

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use crate::tokenstream::TokenTree;
1414

1515
use errors::{Applicability, DiagnosticBuilder, Handler};
1616
use rustc_data_structures::fx::FxHashMap;
17-
use rustc_target::spec::abi::Abi;
1817
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
1918
use log::debug;
2019

@@ -185,62 +184,70 @@ macro_rules! gate_feature_post {
185184
}
186185

187186
impl<'a> PostExpansionVisitor<'a> {
188-
fn check_abi(&self, abi: Abi, span: Span) {
189-
match abi {
190-
Abi::RustIntrinsic => {
187+
fn check_abi(&self, abi: ast::Abi) {
188+
let ast::Abi { symbol, span } = abi;
189+
190+
match &*symbol.as_str() {
191+
// Stable
192+
"Rust" |
193+
"C" |
194+
"cdecl" |
195+
"stdcall" |
196+
"fastcall" |
197+
"aapcs" |
198+
"win64" |
199+
"sysv64" |
200+
"system" => {}
201+
"rust-intrinsic" => {
191202
gate_feature_post!(&self, intrinsics, span,
192203
"intrinsics are subject to change");
193204
},
194-
Abi::PlatformIntrinsic => {
205+
"platform-intrinsic" => {
195206
gate_feature_post!(&self, platform_intrinsics, span,
196207
"platform intrinsics are experimental and possibly buggy");
197208
},
198-
Abi::Vectorcall => {
209+
"vectorcall" => {
199210
gate_feature_post!(&self, abi_vectorcall, span,
200211
"vectorcall is experimental and subject to change");
201212
},
202-
Abi::Thiscall => {
213+
"thiscall" => {
203214
gate_feature_post!(&self, abi_thiscall, span,
204215
"thiscall is experimental and subject to change");
205216
},
206-
Abi::RustCall => {
217+
"rust-call" => {
207218
gate_feature_post!(&self, unboxed_closures, span,
208219
"rust-call ABI is subject to change");
209220
},
210-
Abi::PtxKernel => {
221+
"ptx-kernel" => {
211222
gate_feature_post!(&self, abi_ptx, span,
212223
"PTX ABIs are experimental and subject to change");
213224
},
214-
Abi::Unadjusted => {
225+
"unadjusted" => {
215226
gate_feature_post!(&self, abi_unadjusted, span,
216227
"unadjusted ABI is an implementation detail and perma-unstable");
217228
},
218-
Abi::Msp430Interrupt => {
229+
"msp430-interrupt" => {
219230
gate_feature_post!(&self, abi_msp430_interrupt, span,
220231
"msp430-interrupt ABI is experimental and subject to change");
221232
},
222-
Abi::X86Interrupt => {
233+
"x86-interrupt" => {
223234
gate_feature_post!(&self, abi_x86_interrupt, span,
224235
"x86-interrupt ABI is experimental and subject to change");
225236
},
226-
Abi::AmdGpuKernel => {
237+
"amdgpu-kernel" => {
227238
gate_feature_post!(&self, abi_amdgpu_kernel, span,
228239
"amdgpu-kernel ABI is experimental and subject to change");
229240
},
230-
Abi::EfiApi => {
241+
"efiapi" => {
231242
gate_feature_post!(&self, abi_efiapi, span,
232243
"efiapi ABI is experimental and subject to change");
233244
},
234-
// Stable
235-
Abi::Cdecl |
236-
Abi::Stdcall |
237-
Abi::Fastcall |
238-
Abi::Aapcs |
239-
Abi::Win64 |
240-
Abi::SysV64 |
241-
Abi::Rust |
242-
Abi::C |
243-
Abi::System => {}
245+
abi => {
246+
self.parse_sess.span_diagnostic.delay_span_bug(
247+
span,
248+
&format!("unrecognized ABI not caught in lowering: {}", abi),
249+
)
250+
}
244251
}
245252
}
246253

@@ -365,7 +372,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
365372
fn visit_item(&mut self, i: &'a ast::Item) {
366373
match i.kind {
367374
ast::ItemKind::ForeignMod(ref foreign_module) => {
368-
self.check_abi(foreign_module.abi, i.span);
375+
self.check_abi(foreign_module.abi);
369376
}
370377

371378
ast::ItemKind::Fn(..) => {
@@ -481,7 +488,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
481488
fn visit_ty(&mut self, ty: &'a ast::Ty) {
482489
match ty.kind {
483490
ast::TyKind::BareFn(ref bare_fn_ty) => {
484-
self.check_abi(bare_fn_ty.abi, ty.span);
491+
self.check_abi(bare_fn_ty.abi);
485492
}
486493
ast::TyKind::Never => {
487494
gate_feature_post!(&self, never_type, ty.span,
@@ -531,7 +538,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
531538
// Stability of const fn methods are covered in
532539
// `visit_trait_item` and `visit_impl_item` below; this is
533540
// because default methods don't pass through this point.
534-
self.check_abi(header.abi, span);
541+
self.check_abi(header.abi);
535542
}
536543

537544
if fn_decl.c_variadic() {
@@ -545,7 +552,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
545552
match ti.kind {
546553
ast::TraitItemKind::Method(ref sig, ref block) => {
547554
if block.is_none() {
548-
self.check_abi(sig.header.abi, ti.span);
555+
self.check_abi(sig.header.abi);
549556
}
550557
if sig.decl.c_variadic() {
551558
gate_feature_post!(&self, c_variadic, ti.span,

src/libsyntax/parse/parser.rs

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ mod diagnostics;
1212
use diagnostics::Error;
1313

1414
use crate::ast::{
15-
self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
15+
self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
1616
IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
1717
};
1818
use crate::parse::{PResult, Directory, DirectoryOwnership};
@@ -28,7 +28,6 @@ use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
2828
use crate::ThinVec;
2929

3030
use errors::{Applicability, DiagnosticId, FatalError};
31-
use rustc_target::spec::abi::{self, Abi};
3231
use syntax_pos::{Span, BytePos, DUMMY_SP, FileName};
3332
use log::debug;
3433

@@ -1209,48 +1208,27 @@ impl<'a> Parser<'a> {
12091208

12101209
/// Parses `extern` followed by an optional ABI string, or nothing.
12111210
fn parse_extern_abi(&mut self) -> PResult<'a, Abi> {
1212-
if self.eat_keyword(kw::Extern) {
1213-
Ok(self.parse_opt_abi()?.unwrap_or(Abi::C))
1211+
Ok(if self.eat_keyword(kw::Extern) {
1212+
let ext_sp = self.prev_span;
1213+
self.parse_opt_abi()?.unwrap_or_else(|| Abi::new(sym::C, ext_sp))
12141214
} else {
1215-
Ok(Abi::Rust)
1216-
}
1215+
Abi::default()
1216+
})
12171217
}
12181218

1219-
/// Parses a string as an ABI spec on an extern type or module. Consumes
1220-
/// the `extern` keyword, if one is found.
1219+
/// Parses a string as an ABI spec on an extern type or module.
12211220
fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
12221221
match self.token.kind {
12231222
token::Literal(token::Lit { kind: token::Str, symbol, suffix }) |
12241223
token::Literal(token::Lit { kind: token::StrRaw(..), symbol, suffix }) => {
12251224
self.expect_no_suffix(self.token.span, "an ABI spec", suffix);
12261225
self.bump();
1227-
match abi::lookup(&symbol.as_str()) {
1228-
Some(abi) => Ok(Some(abi)),
1229-
None => {
1230-
self.error_on_invalid_abi(symbol);
1231-
Ok(None)
1232-
}
1233-
}
1226+
Ok(Some(Abi::new(symbol, self.prev_span)))
12341227
}
12351228
_ => Ok(None),
12361229
}
12371230
}
12381231

1239-
/// Emit an error where `symbol` is an invalid ABI.
1240-
fn error_on_invalid_abi(&self, symbol: Symbol) {
1241-
let prev_span = self.prev_span;
1242-
struct_span_err!(
1243-
self.sess.span_diagnostic,
1244-
prev_span,
1245-
E0703,
1246-
"invalid ABI: found `{}`",
1247-
symbol
1248-
)
1249-
.span_label(prev_span, "invalid ABI")
1250-
.help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
1251-
.emit();
1252-
}
1253-
12541232
/// We are parsing `async fn`. If we are on Rust 2015, emit an error.
12551233
fn ban_async_in_2015(&self, async_span: Span) {
12561234
if async_span.rust_2015() {

0 commit comments

Comments
 (0)