@@ -20,20 +20,20 @@ use crate::util::{ExprToSpannedString, expr_to_spanned_string};
20
20
21
21
/// An argument to one of the `asm!` macros. The argument is syntactically valid, but is otherwise
22
22
/// not validated at all.
23
- pub struct RawAsmArg {
24
- pub kind : RawAsmArgKind ,
23
+ pub struct AsmArg {
24
+ pub kind : AsmArgKind ,
25
25
pub span : Span ,
26
26
}
27
27
28
- pub enum RawAsmArgKind {
28
+ pub enum AsmArgKind {
29
29
Template ( P < ast:: Expr > ) ,
30
30
Operand ( Option < Symbol > , ast:: InlineAsmOperand ) ,
31
31
Options ( Vec < ( Symbol , ast:: InlineAsmOptions , Span , Span ) > ) ,
32
32
ClobberAbi ( Vec < ( Symbol , Span ) > ) ,
33
33
}
34
34
35
35
/// Validated assembly arguments, ready for macro expansion.
36
- struct AsmArgs {
36
+ struct ValidatedAsmArgs {
37
37
pub templates : Vec < P < ast:: Expr > > ,
38
38
pub operands : Vec < ( ast:: InlineAsmOperand , Span ) > ,
39
39
named_args : FxIndexMap < Symbol , usize > ,
@@ -145,11 +145,11 @@ fn parse_asm_operand<'a>(
145
145
}
146
146
147
147
// Public for rustfmt.
148
- pub fn parse_raw_asm_args < ' a > (
148
+ pub fn parse_asm_args < ' a > (
149
149
p : & mut Parser < ' a > ,
150
150
sp : Span ,
151
151
asm_macro : AsmMacro ,
152
- ) -> PResult < ' a , Vec < RawAsmArg > > {
152
+ ) -> PResult < ' a , Vec < AsmArg > > {
153
153
let dcx = p. dcx ( ) ;
154
154
155
155
if p. token == token:: Eof {
@@ -159,10 +159,7 @@ pub fn parse_raw_asm_args<'a>(
159
159
let mut args = Vec :: new ( ) ;
160
160
161
161
let first_template = p. parse_expr ( ) ?;
162
- args. push ( RawAsmArg {
163
- span : first_template. span ,
164
- kind : RawAsmArgKind :: Template ( first_template) ,
165
- } ) ;
162
+ args. push ( AsmArg { span : first_template. span , kind : AsmArgKind :: Template ( first_template) } ) ;
166
163
167
164
let mut allow_templates = true ;
168
165
@@ -188,8 +185,8 @@ pub fn parse_raw_asm_args<'a>(
188
185
if p. eat_keyword ( exp ! ( ClobberAbi ) ) {
189
186
allow_templates = false ;
190
187
191
- args. push ( RawAsmArg {
192
- kind : RawAsmArgKind :: ClobberAbi ( parse_clobber_abi ( p) ?) ,
188
+ args. push ( AsmArg {
189
+ kind : AsmArgKind :: ClobberAbi ( parse_clobber_abi ( p) ?) ,
193
190
span : span_start. to ( p. prev_token . span ) ,
194
191
} ) ;
195
192
@@ -200,8 +197,8 @@ pub fn parse_raw_asm_args<'a>(
200
197
if p. eat_keyword ( exp ! ( Options ) ) {
201
198
allow_templates = false ;
202
199
203
- args. push ( RawAsmArg {
204
- kind : RawAsmArgKind :: Options ( parse_options ( p, asm_macro) ?) ,
200
+ args. push ( AsmArg {
201
+ kind : AsmArgKind :: Options ( parse_options ( p, asm_macro) ?) ,
205
202
span : span_start. to ( p. prev_token . span ) ,
206
203
} ) ;
207
204
@@ -222,9 +219,9 @@ pub fn parse_raw_asm_args<'a>(
222
219
if let Some ( op) = parse_asm_operand ( p, asm_macro) ? {
223
220
allow_templates = false ;
224
221
225
- args. push ( RawAsmArg {
222
+ args. push ( AsmArg {
226
223
span : span_start. to ( p. prev_token . span ) ,
227
- kind : RawAsmArgKind :: Operand ( name, op) ,
224
+ kind : AsmArgKind :: Operand ( name, op) ,
228
225
} ) ;
229
226
} else if allow_templates {
230
227
let template = p. parse_expr ( ) ?;
@@ -246,7 +243,7 @@ pub fn parse_raw_asm_args<'a>(
246
243
}
247
244
}
248
245
249
- args. push ( RawAsmArg { span : template. span , kind : RawAsmArgKind :: Template ( template) } ) ;
246
+ args. push ( AsmArg { span : template. span , kind : AsmArgKind :: Template ( template) } ) ;
250
247
} else {
251
248
p. unexpected_any ( ) ?
252
249
}
@@ -260,19 +257,19 @@ fn parse_args<'a>(
260
257
sp : Span ,
261
258
tts : TokenStream ,
262
259
asm_macro : AsmMacro ,
263
- ) -> PResult < ' a , AsmArgs > {
264
- let raw_args = parse_raw_asm_args ( & mut ecx. new_parser_from_tts ( tts) , sp, asm_macro) ?;
265
- validate_raw_asm_args ( ecx, asm_macro, raw_args )
260
+ ) -> PResult < ' a , ValidatedAsmArgs > {
261
+ let args = parse_asm_args ( & mut ecx. new_parser_from_tts ( tts) , sp, asm_macro) ?;
262
+ validate_asm_args ( ecx, asm_macro, args )
266
263
}
267
264
268
- fn validate_raw_asm_args < ' a > (
265
+ fn validate_asm_args < ' a > (
269
266
ecx : & ExtCtxt < ' a > ,
270
267
asm_macro : AsmMacro ,
271
- raw_args : Vec < RawAsmArg > ,
272
- ) -> PResult < ' a , AsmArgs > {
268
+ args : Vec < AsmArg > ,
269
+ ) -> PResult < ' a , ValidatedAsmArgs > {
273
270
let dcx = ecx. dcx ( ) ;
274
271
275
- let mut args = AsmArgs {
272
+ let mut validated = ValidatedAsmArgs {
276
273
templates : vec ! [ ] ,
277
274
operands : vec ! [ ] ,
278
275
named_args : Default :: default ( ) ,
@@ -284,9 +281,9 @@ fn validate_raw_asm_args<'a>(
284
281
285
282
let mut allow_templates = true ;
286
283
287
- for arg in raw_args {
284
+ for arg in args {
288
285
match arg. kind {
289
- RawAsmArgKind :: Template ( template) => {
286
+ AsmArgKind :: Template ( template) => {
290
287
// The error for the first template is delayed.
291
288
if !allow_templates {
292
289
match template. kind {
@@ -306,15 +303,15 @@ fn validate_raw_asm_args<'a>(
306
303
}
307
304
}
308
305
309
- args . templates . push ( template) ;
306
+ validated . templates . push ( template) ;
310
307
}
311
- RawAsmArgKind :: Operand ( name, op) => {
308
+ AsmArgKind :: Operand ( name, op) => {
312
309
allow_templates = false ;
313
310
314
311
let explicit_reg = matches ! ( op. reg( ) , Some ( ast:: InlineAsmRegOrRegClass :: Reg ( _) ) ) ;
315
312
let span = arg. span ;
316
- let slot = args . operands . len ( ) ;
317
- args . operands . push ( ( op, span) ) ;
313
+ let slot = validated . operands . len ( ) ;
314
+ validated . operands . push ( ( op, span) ) ;
318
315
319
316
// Validate the order of named, positional & explicit register operands and
320
317
// clobber_abi/options. We do this at the end once we have the full span
@@ -324,25 +321,27 @@ fn validate_raw_asm_args<'a>(
324
321
if name. is_some ( ) {
325
322
dcx. emit_err ( errors:: AsmExplicitRegisterName { span } ) ;
326
323
}
327
- args . reg_args . insert ( slot) ;
324
+ validated . reg_args . insert ( slot) ;
328
325
} else if let Some ( name) = name {
329
- if let Some ( & prev) = args . named_args . get ( & name) {
326
+ if let Some ( & prev) = validated . named_args . get ( & name) {
330
327
dcx. emit_err ( errors:: AsmDuplicateArg {
331
328
span,
332
329
name,
333
- prev : args . operands [ prev] . 1 ,
330
+ prev : validated . operands [ prev] . 1 ,
334
331
} ) ;
335
332
continue ;
336
333
}
337
- args. named_args . insert ( name, slot) ;
338
- } else if !args. named_args . is_empty ( ) || !args. reg_args . is_empty ( ) {
339
- let named = args. named_args . values ( ) . map ( |p| args. operands [ * p] . 1 ) . collect ( ) ;
340
- let explicit = args. reg_args . iter ( ) . map ( |p| args. operands [ p] . 1 ) . collect ( ) ;
334
+ validated. named_args . insert ( name, slot) ;
335
+ } else if !validated. named_args . is_empty ( ) || !validated. reg_args . is_empty ( ) {
336
+ let named =
337
+ validated. named_args . values ( ) . map ( |p| validated. operands [ * p] . 1 ) . collect ( ) ;
338
+ let explicit =
339
+ validated. reg_args . iter ( ) . map ( |p| validated. operands [ p] . 1 ) . collect ( ) ;
341
340
342
341
dcx. emit_err ( errors:: AsmPositionalAfter { span, named, explicit } ) ;
343
342
}
344
343
}
345
- RawAsmArgKind :: Options ( new_options) => {
344
+ AsmArgKind :: Options ( new_options) => {
346
345
allow_templates = false ;
347
346
348
347
for ( symbol, option, span, full_span) in new_options {
@@ -354,53 +353,55 @@ fn validate_raw_asm_args<'a>(
354
353
full_span,
355
354
macro_name : asm_macro. macro_name ( ) ,
356
355
} ) ;
357
- } else if args . options . contains ( option) {
356
+ } else if validated . options . contains ( option) {
358
357
// Tool-only output.
359
358
dcx. emit_err ( errors:: AsmOptAlreadyprovided { span, symbol, full_span } ) ;
360
359
} else {
361
- args . options |= option;
360
+ validated . options |= option;
362
361
}
363
362
}
364
363
365
- args . options_spans . push ( arg. span ) ;
364
+ validated . options_spans . push ( arg. span ) ;
366
365
}
367
- RawAsmArgKind :: ClobberAbi ( new_abis) => {
366
+ AsmArgKind :: ClobberAbi ( new_abis) => {
368
367
allow_templates = false ;
369
368
370
369
match & new_abis[ ..] {
371
370
// This should have errored above during parsing.
372
371
[ ] => unreachable ! ( ) ,
373
- [ ( abi, _span) ] => args . clobber_abis . push ( ( * abi, arg. span ) ) ,
374
- _ => args . clobber_abis . extend ( new_abis) ,
372
+ [ ( abi, _span) ] => validated . clobber_abis . push ( ( * abi, arg. span ) ) ,
373
+ _ => validated . clobber_abis . extend ( new_abis) ,
375
374
}
376
375
}
377
376
}
378
377
}
379
378
380
- if args . options . contains ( ast:: InlineAsmOptions :: NOMEM )
381
- && args . options . contains ( ast:: InlineAsmOptions :: READONLY )
379
+ if validated . options . contains ( ast:: InlineAsmOptions :: NOMEM )
380
+ && validated . options . contains ( ast:: InlineAsmOptions :: READONLY )
382
381
{
383
- let spans = args . options_spans . clone ( ) ;
382
+ let spans = validated . options_spans . clone ( ) ;
384
383
dcx. emit_err ( errors:: AsmMutuallyExclusive { spans, opt1 : "nomem" , opt2 : "readonly" } ) ;
385
384
}
386
- if args . options . contains ( ast:: InlineAsmOptions :: PURE )
387
- && args . options . contains ( ast:: InlineAsmOptions :: NORETURN )
385
+ if validated . options . contains ( ast:: InlineAsmOptions :: PURE )
386
+ && validated . options . contains ( ast:: InlineAsmOptions :: NORETURN )
388
387
{
389
- let spans = args . options_spans . clone ( ) ;
388
+ let spans = validated . options_spans . clone ( ) ;
390
389
dcx. emit_err ( errors:: AsmMutuallyExclusive { spans, opt1 : "pure" , opt2 : "noreturn" } ) ;
391
390
}
392
- if args. options . contains ( ast:: InlineAsmOptions :: PURE )
393
- && !args. options . intersects ( ast:: InlineAsmOptions :: NOMEM | ast:: InlineAsmOptions :: READONLY )
391
+ if validated. options . contains ( ast:: InlineAsmOptions :: PURE )
392
+ && !validated
393
+ . options
394
+ . intersects ( ast:: InlineAsmOptions :: NOMEM | ast:: InlineAsmOptions :: READONLY )
394
395
{
395
- let spans = args . options_spans . clone ( ) ;
396
+ let spans = validated . options_spans . clone ( ) ;
396
397
dcx. emit_err ( errors:: AsmPureCombine { spans } ) ;
397
398
}
398
399
399
400
let mut have_real_output = false ;
400
401
let mut outputs_sp = vec ! [ ] ;
401
402
let mut regclass_outputs = vec ! [ ] ;
402
403
let mut labels_sp = vec ! [ ] ;
403
- for ( op, op_sp) in & args . operands {
404
+ for ( op, op_sp) in & validated . operands {
404
405
match op {
405
406
ast:: InlineAsmOperand :: Out { reg, expr, .. }
406
407
| ast:: InlineAsmOperand :: SplitInOut { reg, out_expr : expr, .. } => {
@@ -423,26 +424,26 @@ fn validate_raw_asm_args<'a>(
423
424
_ => { }
424
425
}
425
426
}
426
- if args . options . contains ( ast:: InlineAsmOptions :: PURE ) && !have_real_output {
427
- dcx. emit_err ( errors:: AsmPureNoOutput { spans : args . options_spans . clone ( ) } ) ;
427
+ if validated . options . contains ( ast:: InlineAsmOptions :: PURE ) && !have_real_output {
428
+ dcx. emit_err ( errors:: AsmPureNoOutput { spans : validated . options_spans . clone ( ) } ) ;
428
429
}
429
- if args . options . contains ( ast:: InlineAsmOptions :: NORETURN )
430
+ if validated . options . contains ( ast:: InlineAsmOptions :: NORETURN )
430
431
&& !outputs_sp. is_empty ( )
431
432
&& labels_sp. is_empty ( )
432
433
{
433
434
let err = dcx. create_err ( errors:: AsmNoReturn { outputs_sp } ) ;
434
435
// Bail out now since this is likely to confuse MIR
435
436
return Err ( err) ;
436
437
}
437
- if args . options . contains ( ast:: InlineAsmOptions :: MAY_UNWIND ) && !labels_sp. is_empty ( ) {
438
+ if validated . options . contains ( ast:: InlineAsmOptions :: MAY_UNWIND ) && !labels_sp. is_empty ( ) {
438
439
dcx. emit_err ( errors:: AsmMayUnwind { labels_sp } ) ;
439
440
}
440
441
441
- if !args . clobber_abis . is_empty ( ) {
442
+ if !validated . clobber_abis . is_empty ( ) {
442
443
match asm_macro {
443
444
AsmMacro :: GlobalAsm | AsmMacro :: NakedAsm => {
444
445
let err = dcx. create_err ( errors:: AsmUnsupportedClobberAbi {
445
- spans : args . clobber_abis . iter ( ) . map ( |( _, span) | * span) . collect ( ) ,
446
+ spans : validated . clobber_abis . iter ( ) . map ( |( _, span) | * span) . collect ( ) ,
446
447
macro_name : asm_macro. macro_name ( ) ,
447
448
} ) ;
448
449
@@ -453,14 +454,14 @@ fn validate_raw_asm_args<'a>(
453
454
if !regclass_outputs. is_empty ( ) {
454
455
dcx. emit_err ( errors:: AsmClobberNoReg {
455
456
spans : regclass_outputs,
456
- clobbers : args . clobber_abis . iter ( ) . map ( |( _, span) | * span) . collect ( ) ,
457
+ clobbers : validated . clobber_abis . iter ( ) . map ( |( _, span) | * span) . collect ( ) ,
457
458
} ) ;
458
459
}
459
460
}
460
461
}
461
462
}
462
463
463
- Ok ( args )
464
+ Ok ( validated )
464
465
}
465
466
466
467
fn parse_options < ' a > (
@@ -566,7 +567,7 @@ fn parse_reg<'a>(p: &mut Parser<'a>) -> PResult<'a, ast::InlineAsmRegOrRegClass>
566
567
fn expand_preparsed_asm (
567
568
ecx : & mut ExtCtxt < ' _ > ,
568
569
asm_macro : AsmMacro ,
569
- args : AsmArgs ,
570
+ args : ValidatedAsmArgs ,
570
571
) -> ExpandResult < Result < ast:: InlineAsm , ErrorGuaranteed > , ( ) > {
571
572
let mut template = vec ! [ ] ;
572
573
// Register operands are implicitly used since they are not allowed to be
0 commit comments