@@ -391,7 +391,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
391391 used[ * pos] = true ;
392392 }
393393
394- let named_pos: FxHashSet < usize > = args. named_args . values ( ) . cloned ( ) . collect ( ) ;
394+ let named_pos: FxHashMap < usize , Symbol > =
395+ args. named_args . iter ( ) . map ( |( & sym, & idx) | ( idx, sym) ) . collect ( ) ;
395396 let mut arg_spans = parser. arg_places . iter ( ) . map ( |span| template_span. from_inner ( * span) ) ;
396397 let mut template = vec ! [ ] ;
397398 for piece in unverified_pieces {
@@ -405,7 +406,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
405406 let operand_idx = match arg. position {
406407 parse:: ArgumentIs ( idx) | parse:: ArgumentImplicitlyIs ( idx) => {
407408 if idx >= args. operands . len ( )
408- || named_pos. contains ( & idx)
409+ || named_pos. contains_key ( & idx)
409410 || args. reg_args . contains ( & idx)
410411 {
411412 let msg = format ! ( "invalid reference to argument at index {}" , idx) ;
@@ -426,7 +427,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
426427 } ;
427428 err. note ( & msg) ;
428429
429- if named_pos. contains ( & idx) {
430+ if named_pos. contains_key ( & idx) {
430431 err. span_label ( args. operands [ idx] . 1 , "named argument" ) ;
431432 err. span_note (
432433 args. operands [ idx] . 1 ,
@@ -480,27 +481,31 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
480481 }
481482 }
482483
483- let operands = args. operands ;
484- let unused_operands: Vec < _ > = used
485- . into_iter ( )
486- . enumerate ( )
487- . filter ( |& ( _, used) | !used)
488- . map ( |( idx, _) | {
489- if named_pos. contains ( & idx) {
490- // named argument
491- ( operands[ idx] . 1 , "named argument never used" )
484+ let mut unused_operands = vec ! [ ] ;
485+ let mut help_str = String :: new ( ) ;
486+ for ( idx, used) in used. into_iter ( ) . enumerate ( ) {
487+ if !used {
488+ let msg = if let Some ( sym) = named_pos. get ( & idx) {
489+ help_str. push_str ( & format ! ( " {{{}}}" , sym) ) ;
490+ "named argument never used"
492491 } else {
493- // positional argument
494- ( operands[ idx] . 1 , "argument never used" )
495- }
496- } )
497- . collect ( ) ;
492+ help_str. push_str ( & format ! ( " {{{}}}" , idx) ) ;
493+ "argument never used"
494+ } ;
495+ unused_operands. push ( ( args. operands [ idx] . 1 , msg) ) ;
496+ }
497+ }
498498 match unused_operands. len ( ) {
499499 0 => { }
500500 1 => {
501501 let ( sp, msg) = unused_operands. into_iter ( ) . next ( ) . unwrap ( ) ;
502502 let mut err = ecx. struct_span_err ( sp, msg) ;
503503 err. span_label ( sp, msg) ;
504+ err. help ( & format ! (
505+ "if this argument is intentionally unused, \
506+ consider using it in an asm comment: `\" /*{} */\" `",
507+ help_str
508+ ) ) ;
504509 err. emit ( ) ;
505510 }
506511 _ => {
@@ -511,6 +516,11 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
511516 for ( sp, msg) in unused_operands {
512517 err. span_label ( sp, msg) ;
513518 }
519+ err. help ( & format ! (
520+ "if these arguments are intentionally unused, \
521+ consider using them in an asm comment: `\" /*{} */\" `",
522+ help_str
523+ ) ) ;
514524 err. emit ( ) ;
515525 }
516526 }
@@ -521,7 +531,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
521531 parser. line_spans . iter ( ) . map ( |span| template_span. from_inner ( * span) ) . collect ( )
522532 } ;
523533
524- let inline_asm = ast:: InlineAsm { template, operands, options : args. options , line_spans } ;
534+ let inline_asm =
535+ ast:: InlineAsm { template, operands : args. operands , options : args. options , line_spans } ;
525536 P ( ast:: Expr {
526537 id : ast:: DUMMY_NODE_ID ,
527538 kind : ast:: ExprKind :: InlineAsm ( P ( inline_asm) ) ,
0 commit comments