@@ -28,10 +28,19 @@ pub struct AsmArg {
2828pub enum AsmArgKind {
2929 Template ( P < ast:: Expr > ) ,
3030 Operand ( Option < Symbol > , ast:: InlineAsmOperand ) ,
31- Options ( Vec < ( Symbol , ast :: InlineAsmOptions , Span , Span ) > ) ,
31+ Options ( Vec < AsmOption > ) ,
3232 ClobberAbi ( Vec < ( Symbol , Span ) > ) ,
3333}
3434
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+
3544/// Validated assembly arguments, ready for macro expansion.
3645struct ValidatedAsmArgs {
3746 pub templates : Vec < P < ast:: Expr > > ,
@@ -344,20 +353,26 @@ fn validate_asm_args<'a>(
344353 AsmArgKind :: Options ( new_options) => {
345354 allow_templates = false ;
346355
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) {
349360 // Tool-only output.
350361 dcx. emit_err ( errors:: AsmUnsupportedOption {
351362 span,
352363 symbol,
353- full_span ,
364+ span_with_comma ,
354365 macro_name : asm_macro. macro_name ( ) ,
355366 } ) ;
356- } else if validated. options . contains ( option ) {
367+ } else if validated. options . contains ( options ) {
357368 // 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+ } ) ;
359374 } else {
360- validated. options |= option ;
375+ validated. options |= asm_option . options ;
361376 }
362377 }
363378
@@ -464,13 +479,10 @@ fn validate_asm_args<'a>(
464479 Ok ( validated)
465480}
466481
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 > > {
471483 p. expect ( exp ! ( OpenParen ) ) ?;
472484
473- let mut options = Vec :: new ( ) ;
485+ let mut asm_options = Vec :: new ( ) ;
474486
475487 while !p. eat ( exp ! ( CloseParen ) ) {
476488 const OPTIONS : [ ( ExpKeywordPair , ast:: InlineAsmOptions ) ; ast:: InlineAsmOptions :: COUNT ] = [
@@ -486,20 +498,20 @@ fn parse_options<'a>(
486498 ] ;
487499
488500 ' blk: {
489- for ( exp, option ) in OPTIONS {
501+ for ( exp, options ) in OPTIONS {
490502 // 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 ) {
492504 p. eat_keyword ( exp)
493505 } else {
494506 p. eat_keyword_noexpect ( exp. kw )
495507 } ;
496508
497509 if kw_matched {
498510 let span = p. prev_token . span ;
499- let full_span =
511+ let span_with_comma =
500512 if p. token == token:: Comma { span. to ( p. token . span ) } else { span } ;
501513
502- options . push ( ( exp. kw , option , span , full_span ) ) ;
514+ asm_options . push ( AsmOption { symbol : exp. kw , span , options , span_with_comma } ) ;
503515 break ' blk;
504516 }
505517 }
@@ -514,7 +526,7 @@ fn parse_options<'a>(
514526 p. expect ( exp ! ( Comma ) ) ?;
515527 }
516528
517- Ok ( options )
529+ Ok ( asm_options )
518530}
519531
520532fn parse_clobber_abi < ' a > ( p : & mut Parser < ' a > ) -> PResult < ' a , Vec < ( Symbol , Span ) > > {
0 commit comments