@@ -28,10 +28,19 @@ pub struct AsmArg {
28
28
pub enum AsmArgKind {
29
29
Template ( P < ast:: Expr > ) ,
30
30
Operand ( Option < Symbol > , ast:: InlineAsmOperand ) ,
31
- Options ( Vec < ( Symbol , ast :: InlineAsmOptions , Span , Span ) > ) ,
31
+ Options ( Vec < AsmOption > ) ,
32
32
ClobberAbi ( Vec < ( Symbol , Span ) > ) ,
33
33
}
34
34
35
+ pub struct AsmOption {
36
+ pub symbol : Symbol ,
37
+ pub span : Span ,
38
+ // A bitset, with only the bit for this option's symbol set.
39
+ pub options : ast:: InlineAsmOptions ,
40
+ // Used when suggesting to remove an option.
41
+ pub span_with_comma : Span ,
42
+ }
43
+
35
44
/// Validated assembly arguments, ready for macro expansion.
36
45
struct ValidatedAsmArgs {
37
46
pub templates : Vec < P < ast:: Expr > > ,
@@ -344,20 +353,26 @@ fn validate_asm_args<'a>(
344
353
AsmArgKind :: Options ( new_options) => {
345
354
allow_templates = false ;
346
355
347
- for ( symbol, option, span, full_span) in new_options {
348
- if !asm_macro. is_supported_option ( option) {
356
+ for asm_option in new_options {
357
+ let AsmOption { span, symbol, span_with_comma, options } = asm_option;
358
+
359
+ if !asm_macro. is_supported_option ( options) {
349
360
// Tool-only output.
350
361
dcx. emit_err ( errors:: AsmUnsupportedOption {
351
362
span,
352
363
symbol,
353
- full_span ,
364
+ span_with_comma ,
354
365
macro_name : asm_macro. macro_name ( ) ,
355
366
} ) ;
356
- } else if validated. options . contains ( option ) {
367
+ } else if validated. options . contains ( options ) {
357
368
// Tool-only output.
358
- dcx. emit_err ( errors:: AsmOptAlreadyprovided { span, symbol, full_span } ) ;
369
+ dcx. emit_err ( errors:: AsmOptAlreadyprovided {
370
+ span,
371
+ symbol,
372
+ span_with_comma,
373
+ } ) ;
359
374
} else {
360
- validated. options |= option ;
375
+ validated. options |= asm_option . options ;
361
376
}
362
377
}
363
378
@@ -464,13 +479,10 @@ fn validate_asm_args<'a>(
464
479
Ok ( validated)
465
480
}
466
481
467
- fn parse_options < ' a > (
468
- p : & mut Parser < ' a > ,
469
- asm_macro : AsmMacro ,
470
- ) -> PResult < ' a , Vec < ( Symbol , ast:: InlineAsmOptions , Span , Span ) > > {
482
+ fn parse_options < ' a > ( p : & mut Parser < ' a > , asm_macro : AsmMacro ) -> PResult < ' a , Vec < AsmOption > > {
471
483
p. expect ( exp ! ( OpenParen ) ) ?;
472
484
473
- let mut options = Vec :: new ( ) ;
485
+ let mut asm_options = Vec :: new ( ) ;
474
486
475
487
while !p. eat ( exp ! ( CloseParen ) ) {
476
488
const OPTIONS : [ ( ExpKeywordPair , ast:: InlineAsmOptions ) ; ast:: InlineAsmOptions :: COUNT ] = [
@@ -486,20 +498,20 @@ fn parse_options<'a>(
486
498
] ;
487
499
488
500
' blk: {
489
- for ( exp, option ) in OPTIONS {
501
+ for ( exp, options ) in OPTIONS {
490
502
// Gives a more accurate list of expected next tokens.
491
- let kw_matched = if asm_macro. is_supported_option ( option ) {
503
+ let kw_matched = if asm_macro. is_supported_option ( options ) {
492
504
p. eat_keyword ( exp)
493
505
} else {
494
506
p. eat_keyword_noexpect ( exp. kw )
495
507
} ;
496
508
497
509
if kw_matched {
498
510
let span = p. prev_token . span ;
499
- let full_span =
511
+ let span_with_comma =
500
512
if p. token == token:: Comma { span. to ( p. token . span ) } else { span } ;
501
513
502
- options . push ( ( exp. kw , option , span , full_span ) ) ;
514
+ asm_options . push ( AsmOption { symbol : exp. kw , span , options , span_with_comma } ) ;
503
515
break ' blk;
504
516
}
505
517
}
@@ -514,7 +526,7 @@ fn parse_options<'a>(
514
526
p. expect ( exp ! ( Comma ) ) ?;
515
527
}
516
528
517
- Ok ( options )
529
+ Ok ( asm_options )
518
530
}
519
531
520
532
fn parse_clobber_abi < ' a > ( p : & mut Parser < ' a > ) -> PResult < ' a , Vec < ( Symbol , Span ) > > {
0 commit comments