Skip to content

Commit beddf67

Browse files
committed
parser: don't hardcode ABIs into grammar
1 parent caf0187 commit beddf67

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
@@ -1216,7 +1216,7 @@ impl<'a> LoweringContext<'a> {
12161216
ImplTraitContext::disallowed(),
12171217
),
12181218
unsafety: this.lower_unsafety(f.unsafety),
1219-
abi: f.abi,
1219+
abi: this.lower_abi(f.abi),
12201220
decl: this.lower_fn_decl(&f.decl, None, false, None),
12211221
param_names: this.lower_fn_params_to_names(&f.decl),
12221222
}))

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;
@@ -735,7 +736,7 @@ impl LoweringContext<'_> {
735736

736737
fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
737738
hir::ForeignMod {
738-
abi: fm.abi,
739+
abi: self.lower_abi(fm.abi),
739740
items: fm.items
740741
.iter()
741742
.map(|x| self.lower_foreign_item(x))
@@ -1291,10 +1292,30 @@ impl LoweringContext<'_> {
12911292
unsafety: self.lower_unsafety(h.unsafety),
12921293
asyncness: self.lower_asyncness(h.asyncness.node),
12931294
constness: self.lower_constness(h.constness),
1294-
abi: h.abi,
1295+
abi: self.lower_abi(h.abi),
12951296
}
12961297
}
12971298

1299+
pub(super) fn lower_abi(&mut self, abi: Abi) -> abi::Abi {
1300+
abi::lookup(&abi.symbol.as_str()).unwrap_or_else(|| {
1301+
self.error_on_invalid_abi(abi);
1302+
abi::Abi::Rust
1303+
})
1304+
}
1305+
1306+
fn error_on_invalid_abi(&self, abi: Abi) {
1307+
struct_span_err!(
1308+
self.sess,
1309+
abi.span,
1310+
E0703,
1311+
"invalid ABI: found `{}`",
1312+
abi.symbol
1313+
)
1314+
.span_label(abi.span, "invalid ABI")
1315+
.help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
1316+
.emit();
1317+
}
1318+
12981319
pub(super) fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
12991320
match u {
13001321
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;
@@ -2358,6 +2357,27 @@ impl Item {
23582357
}
23592358
}
23602359

2360+
/// A reference to an ABI.
2361+
///
2362+
/// In AST our notion of an ABI is still syntactic unlike in `rustc_target::spec::abi::Abi`.
2363+
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, PartialEq)]
2364+
pub struct Abi {
2365+
pub symbol: Symbol,
2366+
pub span: Span,
2367+
}
2368+
2369+
impl Abi {
2370+
pub fn new(symbol: Symbol, span: Span) -> Self {
2371+
Self { symbol, span }
2372+
}
2373+
}
2374+
2375+
impl Default for Abi {
2376+
fn default() -> Self {
2377+
Self::new(sym::Rust, DUMMY_SP)
2378+
}
2379+
}
2380+
23612381
/// A function header.
23622382
///
23632383
/// All the information between the visibility and the name of the function is
@@ -2376,7 +2396,7 @@ impl Default for FnHeader {
23762396
unsafety: Unsafety::Normal,
23772397
asyncness: dummy_spanned(IsAsync::NotAsync),
23782398
constness: dummy_spanned(Constness::NotConst),
2379-
abi: Abi::Rust,
2399+
abi: Abi::default(),
23802400
}
23812401
}
23822402
}

src/libsyntax/error_codes.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,5 @@ equivalent in Rust would be to use macros directly.
540540
E0630,
541541
E0693, // incorrect `repr(align)` attribute format
542542
// E0694, // an unknown tool name found in scoped attributes
543-
E0703, // invalid ABI
544543
E0717, // rustc_promotable without stability attribute
545544
}

src/libsyntax/feature_gate/check.rs

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

1919
use errors::{Applicability, DiagnosticBuilder, Handler};
2020
use rustc_data_structures::fx::FxHashMap;
21-
use rustc_target::spec::abi::Abi;
2221
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
2322
use log::debug;
2423

@@ -192,62 +191,70 @@ macro_rules! gate_feature_post {
192191
}
193192

194193
impl<'a> PostExpansionVisitor<'a> {
195-
fn check_abi(&self, abi: Abi, span: Span) {
196-
match abi {
197-
Abi::RustIntrinsic => {
194+
fn check_abi(&self, abi: ast::Abi) {
195+
let ast::Abi { symbol, span } = abi;
196+
197+
match &*symbol.as_str() {
198+
// Stable
199+
"Rust" |
200+
"C" |
201+
"cdecl" |
202+
"stdcall" |
203+
"fastcall" |
204+
"aapcs" |
205+
"win64" |
206+
"sysv64" |
207+
"system" => {}
208+
"rust-intrinsic" => {
198209
gate_feature_post!(&self, intrinsics, span,
199210
"intrinsics are subject to change");
200211
},
201-
Abi::PlatformIntrinsic => {
212+
"platform-intrinsic" => {
202213
gate_feature_post!(&self, platform_intrinsics, span,
203214
"platform intrinsics are experimental and possibly buggy");
204215
},
205-
Abi::Vectorcall => {
216+
"vectorcall" => {
206217
gate_feature_post!(&self, abi_vectorcall, span,
207218
"vectorcall is experimental and subject to change");
208219
},
209-
Abi::Thiscall => {
220+
"thiscall" => {
210221
gate_feature_post!(&self, abi_thiscall, span,
211222
"thiscall is experimental and subject to change");
212223
},
213-
Abi::RustCall => {
224+
"rust-call" => {
214225
gate_feature_post!(&self, unboxed_closures, span,
215226
"rust-call ABI is subject to change");
216227
},
217-
Abi::PtxKernel => {
228+
"ptx-kernel" => {
218229
gate_feature_post!(&self, abi_ptx, span,
219230
"PTX ABIs are experimental and subject to change");
220231
},
221-
Abi::Unadjusted => {
232+
"unadjusted" => {
222233
gate_feature_post!(&self, abi_unadjusted, span,
223234
"unadjusted ABI is an implementation detail and perma-unstable");
224235
},
225-
Abi::Msp430Interrupt => {
236+
"msp430-interrupt" => {
226237
gate_feature_post!(&self, abi_msp430_interrupt, span,
227238
"msp430-interrupt ABI is experimental and subject to change");
228239
},
229-
Abi::X86Interrupt => {
240+
"x86-interrupt" => {
230241
gate_feature_post!(&self, abi_x86_interrupt, span,
231242
"x86-interrupt ABI is experimental and subject to change");
232243
},
233-
Abi::AmdGpuKernel => {
244+
"amdgpu-kernel" => {
234245
gate_feature_post!(&self, abi_amdgpu_kernel, span,
235246
"amdgpu-kernel ABI is experimental and subject to change");
236247
},
237-
Abi::EfiApi => {
248+
"efiapi" => {
238249
gate_feature_post!(&self, abi_efiapi, span,
239250
"efiapi ABI is experimental and subject to change");
240251
},
241-
// Stable
242-
Abi::Cdecl |
243-
Abi::Stdcall |
244-
Abi::Fastcall |
245-
Abi::Aapcs |
246-
Abi::Win64 |
247-
Abi::SysV64 |
248-
Abi::Rust |
249-
Abi::C |
250-
Abi::System => {}
252+
abi => {
253+
self.parse_sess.span_diagnostic.delay_span_bug(
254+
span,
255+
&format!("unrecognized ABI not caught in lowering: {}", abi),
256+
)
257+
}
251258
}
252259
}
253260

@@ -373,7 +380,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
373380
fn visit_item(&mut self, i: &'a ast::Item) {
374381
match i.kind {
375382
ast::ItemKind::ForeignMod(ref foreign_module) => {
376-
self.check_abi(foreign_module.abi, i.span);
383+
self.check_abi(foreign_module.abi);
377384
}
378385

379386
ast::ItemKind::Fn(..) => {
@@ -503,7 +510,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
503510
fn visit_ty(&mut self, ty: &'a ast::Ty) {
504511
match ty.kind {
505512
ast::TyKind::BareFn(ref bare_fn_ty) => {
506-
self.check_abi(bare_fn_ty.abi, ty.span);
513+
self.check_abi(bare_fn_ty.abi);
507514
}
508515
ast::TyKind::Never => {
509516
gate_feature_post!(&self, never_type, ty.span,
@@ -597,7 +604,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
597604
// Stability of const fn methods are covered in
598605
// `visit_trait_item` and `visit_impl_item` below; this is
599606
// because default methods don't pass through this point.
600-
self.check_abi(header.abi, span);
607+
self.check_abi(header.abi);
601608
}
602609

603610
if fn_decl.c_variadic() {
@@ -631,7 +638,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
631638
match ti.kind {
632639
ast::TraitItemKind::Method(ref sig, ref block) => {
633640
if block.is_none() {
634-
self.check_abi(sig.header.abi, ti.span);
641+
self.check_abi(sig.header.abi);
635642
}
636643
if sig.decl.c_variadic() {
637644
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, DiagnosticBuilder, DiagnosticId, FatalError};
31-
use rustc_target::spec::abi::{self, Abi};
3231
use syntax_pos::{Span, BytePos, DUMMY_SP, FileName};
3332
use log::debug;
3433

@@ -1208,48 +1207,27 @@ impl<'a> Parser<'a> {
12081207

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

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

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

0 commit comments

Comments
 (0)