Skip to content

Commit 00bc449

Browse files
committed
ast: Keep string literals in ABIs precisely
1 parent 266f547 commit 00bc449

File tree

6 files changed

+49
-30
lines changed

6 files changed

+49
-30
lines changed

src/librustc/hir/lowering/item.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,8 +1287,8 @@ impl LoweringContext<'_> {
12871287
}
12881288
}
12891289

1290-
pub(super) fn lower_abi(&mut self, abi: Abi) -> abi::Abi {
1291-
abi::lookup(&abi.symbol.as_str()).unwrap_or_else(|| {
1290+
pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
1291+
abi::lookup(&abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
12921292
self.error_on_invalid_abi(abi);
12931293
abi::Abi::Rust
12941294
})
@@ -1302,7 +1302,7 @@ impl LoweringContext<'_> {
13021302
}
13031303
}
13041304

1305-
fn error_on_invalid_abi(&self, abi: Abi) {
1305+
fn error_on_invalid_abi(&self, abi: StrLit) {
13061306
struct_span_err!(
13071307
self.sess,
13081308
abi.span,

src/librustc_parse/parser/item.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,7 @@ impl<'a> Parser<'a> {
11001100
fn parse_item_foreign_mod(
11011101
&mut self,
11021102
lo: Span,
1103-
abi: Option<Abi>,
1103+
abi: Option<StrLit>,
11041104
visibility: Visibility,
11051105
mut attrs: Vec<Attribute>,
11061106
extern_sp: Span,
@@ -1778,7 +1778,7 @@ impl<'a> Parser<'a> {
17781778
let is_c_abi = match header.ext {
17791779
ast::Extern::None => false,
17801780
ast::Extern::Implicit => true,
1781-
ast::Extern::Explicit(abi) => abi.symbol == sym::C,
1781+
ast::Extern::Explicit(abi) => abi.symbol_unescaped == sym::C,
17821782
};
17831783
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
17841784
is_self_allowed: false,

src/librustc_parse/parser/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{Directory, DirectoryOwnership};
1515
use crate::lexer::UnmatchedBrace;
1616

1717
use syntax::ast::{
18-
self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident,
18+
self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident,
1919
IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
2020
};
2121

@@ -1221,11 +1221,14 @@ impl<'a> Parser<'a> {
12211221
}
12221222

12231223
/// Parses a string literal as an ABI spec.
1224-
fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
1224+
fn parse_opt_abi(&mut self) -> PResult<'a, Option<StrLit>> {
12251225
if self.token.can_begin_literal_or_bool() {
1226-
let ast::Lit { span, kind, .. } = self.parse_lit()?;
1226+
let ast::Lit { token: token::Lit { symbol, suffix, .. }, span, kind }
1227+
= self.parse_lit()?;
12271228
match kind {
1228-
ast::LitKind::Str(symbol, _) => return Ok(Some(Abi { symbol, span })),
1229+
ast::LitKind::Str(symbol_unescaped, style) => return Ok(Some(StrLit {
1230+
style, symbol, suffix, span, symbol_unescaped,
1231+
})),
12291232
ast::LitKind::Err(_) => {}
12301233
_ => {
12311234
self.struct_span_err(span, "non-string ABI literal")

src/libsyntax/ast.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,33 @@ pub struct Lit {
14221422
pub span: Span,
14231423
}
14241424

1425+
/// Same as `Lit`, but restricted to string literals.
1426+
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
1427+
pub struct StrLit {
1428+
/// The original literal token as written in source code.
1429+
pub style: StrStyle,
1430+
pub symbol: Symbol,
1431+
pub suffix: Option<Symbol>,
1432+
pub span: Span,
1433+
/// The unescaped "semantic" representation of the literal lowered from the original token.
1434+
/// FIXME: Remove this and only create the semantic representation during lowering to HIR.
1435+
pub symbol_unescaped: Symbol,
1436+
}
1437+
1438+
impl StrLit {
1439+
crate fn as_lit(&self) -> Lit {
1440+
let token_kind = match self.style {
1441+
StrStyle::Cooked => token::Str,
1442+
StrStyle::Raw(n) => token::StrRaw(n),
1443+
};
1444+
Lit {
1445+
token: token::Lit::new(token_kind, self.symbol, self.suffix),
1446+
span: self.span,
1447+
kind: LitKind::Str(self.symbol_unescaped, self.style),
1448+
}
1449+
}
1450+
}
1451+
14251452
// Clippy uses Hash and PartialEq
14261453
/// Type of the integer literal based on provided suffix.
14271454
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
@@ -2128,7 +2155,7 @@ pub struct Mod {
21282155
/// E.g., `extern { .. }` or `extern C { .. }`.
21292156
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
21302157
pub struct ForeignMod {
2131-
pub abi: Option<Abi>,
2158+
pub abi: Option<StrLit>,
21322159
pub items: Vec<ForeignItem>,
21332160
}
21342161

@@ -2411,25 +2438,16 @@ impl Item {
24112438
}
24122439
}
24132440

2414-
/// A reference to an ABI.
2415-
///
2416-
/// In AST our notion of an ABI is still syntactic unlike in `rustc_target::spec::abi::Abi`.
2417-
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, PartialEq)]
2418-
pub struct Abi {
2419-
pub symbol: Symbol,
2420-
pub span: Span,
2421-
}
2422-
24232441
/// `extern` qualifier on a function item or function type.
24242442
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
24252443
pub enum Extern {
24262444
None,
24272445
Implicit,
2428-
Explicit(Abi),
2446+
Explicit(StrLit),
24292447
}
24302448

24312449
impl Extern {
2432-
pub fn from_abi(abi: Option<Abi>) -> Extern {
2450+
pub fn from_abi(abi: Option<StrLit>) -> Extern {
24332451
match abi {
24342452
Some(abi) => Extern::Explicit(abi),
24352453
None => Extern::Implicit,

src/libsyntax/feature_gate/check.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,10 @@ macro_rules! gate_feature_post {
191191
}
192192

193193
impl<'a> PostExpansionVisitor<'a> {
194-
fn check_abi(&self, abi: ast::Abi) {
195-
let ast::Abi { symbol, span } = abi;
194+
fn check_abi(&self, abi: ast::StrLit) {
195+
let ast::StrLit { symbol_unescaped, span, .. } = abi;
196196

197-
match &*symbol.as_str() {
197+
match &*symbol_unescaped.as_str() {
198198
// Stable
199199
"Rust" |
200200
"C" |

src/libsyntax/print/pprust.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,8 @@ impl<'a> State<'a> {
12331233
ast::ItemKind::ForeignMod(ref nmod) => {
12341234
self.head("extern");
12351235
if let Some(abi) = nmod.abi {
1236-
self.print_abi(abi);
1236+
self.print_literal(&abi.as_lit());
1237+
self.nbsp();
12371238
}
12381239
self.bopen();
12391240
self.print_foreign_mod(nmod, &item.attrs);
@@ -2875,17 +2876,14 @@ impl<'a> State<'a> {
28752876
}
28762877
ast::Extern::Explicit(abi) => {
28772878
self.word_nbsp("extern");
2878-
self.print_abi(abi);
2879+
self.print_literal(&abi.as_lit());
2880+
self.nbsp();
28792881
}
28802882
}
28812883

28822884
self.s.word("fn")
28832885
}
28842886

2885-
fn print_abi(&mut self, abi: ast::Abi) {
2886-
self.word_nbsp(format!("\"{}\"", abi.symbol));
2887-
}
2888-
28892887
crate fn print_unsafety(&mut self, s: ast::Unsafety) {
28902888
match s {
28912889
ast::Unsafety::Normal => {},

0 commit comments

Comments
 (0)