Skip to content

Commit a699f17

Browse files
committed
parse: Use string literal parsing in the asm macro
1 parent b85a3da commit a699f17

File tree

4 files changed

+56
-59
lines changed

4 files changed

+56
-59
lines changed

src/librustc_parse/parser/expr.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,22 @@ impl<'a> Parser<'a> {
10731073
self.maybe_recover_from_bad_qpath(expr, true)
10741074
}
10751075

1076+
pub fn parse_str_lit(&mut self) -> Result<ast::StrLit, Option<Lit>> {
1077+
match self.parse_opt_lit() {
1078+
Some(lit) => match lit.kind {
1079+
ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit {
1080+
style,
1081+
symbol: lit.token.symbol,
1082+
suffix: lit.token.suffix,
1083+
span: lit.span,
1084+
symbol_unescaped,
1085+
}),
1086+
_ => Err(Some(lit)),
1087+
}
1088+
None => Err(None),
1089+
}
1090+
}
1091+
10761092
pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
10771093
self.parse_opt_lit().ok_or_else(|| {
10781094
let msg = format!("unexpected token: {}", self.this_token_descr());

src/librustc_parse/parser/item.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use super::diagnostics::{Error, dummy_arg, ConsumeClosingDelim};
33

44
use crate::maybe_whole;
55

6-
use syntax::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
6+
use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
77
use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
8-
use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
8+
use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
99
use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
1010
use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, VariantData, StructField};
1111
use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param};
@@ -105,7 +105,7 @@ impl<'a> Parser<'a> {
105105
return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?));
106106
}
107107

108-
let abi = self.parse_opt_abi();
108+
let abi = self.parse_abi();
109109

110110
if self.eat_keyword(kw::Fn) {
111111
// EXTERN FUNCTION ITEM

src/librustc_parse/parser/mod.rs

+12-42
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use crate::{Directory, DirectoryOwnership};
1515
use crate::lexer::UnmatchedBrace;
1616

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

2222
use syntax::print::pprust;
@@ -1214,34 +1214,32 @@ impl<'a> Parser<'a> {
12141214
/// Parses `extern string_literal?`.
12151215
fn parse_extern(&mut self) -> PResult<'a, Extern> {
12161216
Ok(if self.eat_keyword(kw::Extern) {
1217-
Extern::from_abi(self.parse_opt_abi())
1217+
Extern::from_abi(self.parse_abi())
12181218
} else {
12191219
Extern::None
12201220
})
12211221
}
12221222

12231223
/// Parses a string literal as an ABI spec.
1224-
fn parse_opt_abi(&mut self) -> Option<StrLit> {
1225-
if let Some(ast::Lit { token: token::Lit { symbol, suffix, .. }, span, kind })
1226-
= self.parse_opt_lit() {
1227-
match kind {
1228-
ast::LitKind::Str(symbol_unescaped, style) => return Some(StrLit {
1229-
style, symbol, suffix, span, symbol_unescaped,
1230-
}),
1231-
ast::LitKind::Err(_) => {}
1224+
fn parse_abi(&mut self) -> Option<StrLit> {
1225+
match self.parse_str_lit() {
1226+
Ok(str_lit) => Some(str_lit),
1227+
Err(Some(lit)) => match lit.kind {
1228+
ast::LitKind::Err(_) => None,
12321229
_ => {
1233-
self.struct_span_err(span, "non-string ABI literal")
1230+
self.struct_span_err(lit.span, "non-string ABI literal")
12341231
.span_suggestion(
1235-
span,
1232+
lit.span,
12361233
"specify the ABI with a string literal",
12371234
"\"C\"".to_string(),
12381235
Applicability::MaybeIncorrect,
12391236
)
12401237
.emit();
1238+
None
12411239
}
12421240
}
1241+
Err(None) => None,
12431242
}
1244-
None
12451243
}
12461244

12471245
/// We are parsing `async fn`. If we are on Rust 2015, emit an error.
@@ -1333,34 +1331,6 @@ impl<'a> Parser<'a> {
13331331
self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace) ||
13341332
*t == token::BinOp(token::Star))
13351333
}
1336-
1337-
fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
1338-
let ret = match self.token.kind {
1339-
token::Literal(token::Lit { kind: token::Str, symbol, suffix }) =>
1340-
(symbol, ast::StrStyle::Cooked, suffix),
1341-
token::Literal(token::Lit { kind: token::StrRaw(n), symbol, suffix }) =>
1342-
(symbol, ast::StrStyle::Raw(n), suffix),
1343-
_ => return None
1344-
};
1345-
self.bump();
1346-
Some(ret)
1347-
}
1348-
1349-
pub fn parse_str(&mut self) -> PResult<'a, (Symbol, StrStyle)> {
1350-
match self.parse_optional_str() {
1351-
Some((s, style, suf)) => {
1352-
let sp = self.prev_span;
1353-
self.expect_no_suffix(sp, "a string literal", suf);
1354-
Ok((s, style))
1355-
}
1356-
_ => {
1357-
let msg = "expected string literal";
1358-
let mut err = self.fatal(msg);
1359-
err.span_label(self.token.span, msg);
1360-
Err(err)
1361-
}
1362-
}
1363-
}
13641334
}
13651335

13661336
crate fn make_unclosed_delims_error(

src/libsyntax_ext/asm.rs

+25-14
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,17 @@
22
//
33
use State::*;
44

5+
use errors::{DiagnosticBuilder, PResult};
56
use rustc_data_structures::thin_vec::ThinVec;
6-
7-
use errors::DiagnosticBuilder;
8-
9-
use syntax::ast;
10-
use syntax_expand::base::{self, *};
11-
use syntax::token::{self, Token};
7+
use rustc_parse::parser::Parser;
8+
use syntax_expand::base::*;
9+
use syntax_pos::Span;
10+
use syntax::{span_err, struct_span_err};
11+
use syntax::ast::{self, AsmDialect};
1212
use syntax::ptr::P;
1313
use syntax::symbol::{kw, sym, Symbol};
14-
use syntax::ast::AsmDialect;
15-
use syntax_pos::Span;
14+
use syntax::token::{self, Token};
1615
use syntax::tokenstream::{self, TokenStream};
17-
use syntax::{span_err, struct_span_err};
1816

1917
use rustc_error_codes::*;
2018

@@ -45,7 +43,7 @@ const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel];
4543
pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
4644
sp: Span,
4745
tts: TokenStream)
48-
-> Box<dyn base::MacResult + 'cx> {
46+
-> Box<dyn MacResult + 'cx> {
4947
let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
5048
Ok(Some(inline_asm)) => inline_asm,
5149
Ok(None) => return DummyResult::any(sp),
@@ -69,6 +67,19 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
6967
}))
7068
}
7169

70+
fn parse_asm_str<'a>(p: &mut Parser<'a>) -> PResult<'a, Symbol> {
71+
match p.parse_str_lit() {
72+
Ok(str_lit) => Ok(str_lit.symbol_unescaped),
73+
Err(opt_lit) => {
74+
let span = opt_lit.map_or(p.token.span, |lit| lit.span);
75+
let msg = "expected string literal";
76+
let mut err = p.sess.span_diagnostic.struct_span_fatal(span, msg);
77+
err.span_label(span, msg);
78+
Err(err)
79+
}
80+
}
81+
}
82+
7283
fn parse_inline_asm<'a>(
7384
cx: &mut ExtCtxt<'a>,
7485
sp: Span,
@@ -144,7 +155,7 @@ fn parse_inline_asm<'a>(
144155
p.eat(&token::Comma);
145156
}
146157

147-
let (constraint, _) = p.parse_str()?;
158+
let constraint = parse_asm_str(&mut p)?;
148159

149160
let span = p.prev_span;
150161

@@ -189,7 +200,7 @@ fn parse_inline_asm<'a>(
189200
p.eat(&token::Comma);
190201
}
191202

192-
let (constraint, _) = p.parse_str()?;
203+
let constraint = parse_asm_str(&mut p)?;
193204

194205
if constraint.as_str().starts_with("=") {
195206
span_err!(cx, p.prev_span, E0662,
@@ -212,7 +223,7 @@ fn parse_inline_asm<'a>(
212223
p.eat(&token::Comma);
213224
}
214225

215-
let (s, _) = p.parse_str()?;
226+
let s = parse_asm_str(&mut p)?;
216227

217228
if OPTIONS.iter().any(|&opt| s == opt) {
218229
cx.span_warn(p.prev_span, "expected a clobber, found an option");
@@ -225,7 +236,7 @@ fn parse_inline_asm<'a>(
225236
}
226237
}
227238
Options => {
228-
let (option, _) = p.parse_str()?;
239+
let option = parse_asm_str(&mut p)?;
229240

230241
if option == sym::volatile {
231242
// Indicates that the inline assembly has side effects

0 commit comments

Comments
 (0)