Skip to content

Commit 2860b75

Browse files
committed
more cleanup
1 parent f39a13a commit 2860b75

File tree

1 file changed

+60
-62
lines changed
  • compiler/rustc_builtin_macros/src

1 file changed

+60
-62
lines changed

compiler/rustc_builtin_macros/src/asm.rs

+60-62
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_ast::ptr::P;
44
use rustc_ast::tokenstream::TokenStream;
55
use rustc_ast::{AsmMacro, token};
66
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
7-
use rustc_errors::PResult;
7+
use rustc_errors::{DiagCtxtHandle, PResult};
88
use rustc_expand::base::*;
99
use rustc_index::bit_set::GrowableBitSet;
1010
use rustc_parse::exp;
@@ -18,10 +18,11 @@ use {rustc_ast as ast, rustc_parse_format as parse};
1818
use crate::errors;
1919
use crate::util::{ExprToSpannedString, expr_to_spanned_string};
2020

21+
/// An argument to one of the `asm!` macros. The argument is syntactically valid, but is otherwise
22+
/// not validated at all.
2123
pub struct RawAsmArg {
22-
pub span: Span,
23-
pub attributes: ast::AttrVec,
2424
pub kind: RawAsmArgKind,
25+
pub span: Span,
2526
}
2627

2728
pub enum RawAsmArgKind {
@@ -31,6 +32,7 @@ pub enum RawAsmArgKind {
3132
ClobberAbi(Vec<(Symbol, Span)>),
3233
}
3334

35+
/// Validated assembly arguments, ready for macro expansion.
3436
pub struct AsmArgs {
3537
pub templates: Vec<P<ast::Expr>>,
3638
pub operands: Vec<(ast::InlineAsmOperand, Span)>,
@@ -72,16 +74,6 @@ fn eat_operand_keyword<'a>(
7274
}
7375
}
7476

75-
fn parse_args<'a>(
76-
ecx: &ExtCtxt<'a>,
77-
sp: Span,
78-
tts: TokenStream,
79-
asm_macro: AsmMacro,
80-
) -> PResult<'a, AsmArgs> {
81-
let mut p = ecx.new_parser_from_tts(tts);
82-
parse_asm_args(&mut p, sp, asm_macro)
83-
}
84-
8577
fn parse_asm_operand<'a>(
8678
p: &mut Parser<'a>,
8779
asm_macro: AsmMacro,
@@ -168,7 +160,6 @@ pub fn parse_raw_asm_args<'a>(
168160
let first_template = p.parse_expr()?;
169161
args.push(RawAsmArg {
170162
span: first_template.span,
171-
attributes: ast::AttrVec::new(),
172163
kind: RawAsmArgKind::Template(first_template),
173164
});
174165

@@ -195,7 +186,6 @@ pub fn parse_raw_asm_args<'a>(
195186
allow_templates = false;
196187

197188
args.push(RawAsmArg {
198-
attributes: ast::AttrVec::new(),
199189
kind: RawAsmArgKind::ClobberAbi(parse_clobber_abi(p)?),
200190
span: span_start.to(p.prev_token.span),
201191
});
@@ -208,7 +198,6 @@ pub fn parse_raw_asm_args<'a>(
208198
allow_templates = false;
209199

210200
args.push(RawAsmArg {
211-
attributes: ast::AttrVec::new(),
212201
kind: RawAsmArgKind::Options(parse_options(p, asm_macro)?),
213202
span: span_start.to(p.prev_token.span),
214203
});
@@ -227,58 +216,68 @@ pub fn parse_raw_asm_args<'a>(
227216
None
228217
};
229218

230-
let Some(op) = parse_asm_operand(p, asm_macro)? else {
231-
if allow_templates {
232-
let template = p.parse_expr()?;
233-
// If it can't possibly expand to a string, provide diagnostics here to include other
234-
// things it could have been.
235-
match template.kind {
236-
ast::ExprKind::Lit(token_lit)
237-
if matches!(
238-
token_lit.kind,
239-
token::LitKind::Str | token::LitKind::StrRaw(_)
240-
) => {}
241-
ast::ExprKind::MacCall(..) => {}
242-
_ => {
243-
let err = dcx.create_err(errors::AsmExpectedOther {
244-
span: template.span,
245-
is_inline_asm: matches!(asm_macro, AsmMacro::Asm),
246-
});
247-
return Err(err);
248-
}
249-
}
250-
251-
args.push(RawAsmArg {
252-
span: template.span,
253-
attributes: ast::AttrVec::new(),
254-
kind: RawAsmArgKind::Template(template),
255-
});
219+
if let Some(op) = parse_asm_operand(p, asm_macro)? {
220+
allow_templates = false;
256221

257-
continue;
258-
} else {
259-
p.unexpected_any()?
222+
args.push(RawAsmArg {
223+
span: span_start.to(p.prev_token.span),
224+
kind: RawAsmArgKind::Operand(name, op),
225+
});
226+
} else if allow_templates {
227+
let template = p.parse_expr()?;
228+
// If it can't possibly expand to a string, provide diagnostics here to include other
229+
// things it could have been.
230+
match template.kind {
231+
ast::ExprKind::Lit(token_lit)
232+
if matches!(
233+
token_lit.kind,
234+
token::LitKind::Str | token::LitKind::StrRaw(_)
235+
) => {}
236+
ast::ExprKind::MacCall(..) => {}
237+
_ => {
238+
let err = dcx.create_err(errors::AsmExpectedOther {
239+
span: template.span,
240+
is_inline_asm: matches!(asm_macro, AsmMacro::Asm),
241+
});
242+
return Err(err);
243+
}
260244
}
261-
};
262245

263-
allow_templates = false;
264-
265-
args.push(RawAsmArg {
266-
span: span_start.to(p.prev_token.span),
267-
attributes: ast::AttrVec::new(),
268-
kind: RawAsmArgKind::Operand(name, op),
269-
});
246+
args.push(RawAsmArg { span: template.span, kind: RawAsmArgKind::Template(template) });
247+
} else {
248+
p.unexpected_any()?
249+
}
270250
}
271251

272252
Ok(args)
273253
}
274254

255+
fn parse_args<'a>(
256+
ecx: &ExtCtxt<'a>,
257+
sp: Span,
258+
tts: TokenStream,
259+
asm_macro: AsmMacro,
260+
) -> PResult<'a, AsmArgs> {
261+
let mut p = ecx.new_parser_from_tts(tts);
262+
parse_asm_args(&mut p, sp, asm_macro)
263+
}
264+
265+
// public for use in rustfmt
266+
// FIXME: use `RawAsmArg` in the formatting code instead.
275267
pub fn parse_asm_args<'a>(
276268
p: &mut Parser<'a>,
277269
sp: Span,
278270
asm_macro: AsmMacro,
279271
) -> PResult<'a, AsmArgs> {
280-
let dcx = p.dcx();
272+
let raw_args = parse_raw_asm_args(p, sp, asm_macro)?;
273+
validate_raw_asm_args(p.dcx(), asm_macro, raw_args)
274+
}
281275

276+
pub fn validate_raw_asm_args<'a>(
277+
dcx: DiagCtxtHandle<'a>,
278+
asm_macro: AsmMacro,
279+
raw_args: Vec<RawAsmArg>,
280+
) -> PResult<'a, AsmArgs> {
282281
let mut args = AsmArgs {
283282
templates: vec![],
284283
operands: vec![],
@@ -291,12 +290,11 @@ pub fn parse_asm_args<'a>(
291290

292291
let mut allow_templates = true;
293292

294-
for arg in parse_raw_asm_args(p, sp, asm_macro)? {
293+
for arg in raw_args {
295294
match arg.kind {
296295
RawAsmArgKind::Template(template) => {
297-
if allow_templates {
298-
args.templates.push(template);
299-
} else {
296+
// The error for the first template is delayed.
297+
if !allow_templates {
300298
match template.kind {
301299
ast::ExprKind::Lit(token_lit)
302300
if matches!(
@@ -312,14 +310,14 @@ pub fn parse_asm_args<'a>(
312310
return Err(err);
313311
}
314312
}
315-
args.templates.push(template);
316313
}
314+
315+
args.templates.push(template);
317316
}
318317
RawAsmArgKind::Operand(name, op) => {
319318
allow_templates = false;
320319

321320
let explicit_reg = matches!(op.reg(), Some(ast::InlineAsmRegOrRegClass::Reg(_)));
322-
323321
let span = arg.span;
324322
let slot = args.operands.len();
325323
args.operands.push((op, span));
@@ -366,7 +364,7 @@ pub fn parse_asm_args<'a>(
366364
*/
367365
} else if args.options.contains(option) {
368366
// Tool-only output
369-
p.dcx().emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
367+
dcx.emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
370368
} else {
371369
args.options |= option;
372370
}
@@ -496,6 +494,7 @@ fn parse_options<'a>(
496494

497495
'blk: {
498496
for (exp, option) in OPTIONS {
497+
// Gives a more accurate list of expected next tokens.
499498
let kw_matched = if asm_macro.is_supported_option(option) {
500499
p.eat_keyword(exp)
501500
} else {
@@ -538,7 +537,6 @@ fn parse_options<'a>(
538537
fn parse_clobber_abi<'a>(p: &mut Parser<'a>) -> PResult<'a, Vec<(Symbol, Span)>> {
539538
p.expect(exp!(OpenParen))?;
540539

541-
// FIXME: why not allow this?
542540
if p.eat(exp!(CloseParen)) {
543541
return Err(p.dcx().create_err(errors::NonABI { span: p.token.span }));
544542
}

0 commit comments

Comments
 (0)