@@ -391,7 +391,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
391
391
used[ * pos] = true ;
392
392
}
393
393
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 ( ) ;
395
396
let mut arg_spans = parser. arg_places . iter ( ) . map ( |span| template_span. from_inner ( * span) ) ;
396
397
let mut template = vec ! [ ] ;
397
398
for piece in unverified_pieces {
@@ -405,7 +406,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
405
406
let operand_idx = match arg. position {
406
407
parse:: ArgumentIs ( idx) | parse:: ArgumentImplicitlyIs ( idx) => {
407
408
if idx >= args. operands . len ( )
408
- || named_pos. contains ( & idx)
409
+ || named_pos. contains_key ( & idx)
409
410
|| args. reg_args . contains ( & idx)
410
411
{
411
412
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
426
427
} ;
427
428
err. note ( & msg) ;
428
429
429
- if named_pos. contains ( & idx) {
430
+ if named_pos. contains_key ( & idx) {
430
431
err. span_label ( args. operands [ idx] . 1 , "named argument" ) ;
431
432
err. span_note (
432
433
args. operands [ idx] . 1 ,
@@ -480,27 +481,31 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
480
481
}
481
482
}
482
483
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"
492
491
} 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
+ }
498
498
match unused_operands. len ( ) {
499
499
0 => { }
500
500
1 => {
501
501
let ( sp, msg) = unused_operands. into_iter ( ) . next ( ) . unwrap ( ) ;
502
502
let mut err = ecx. struct_span_err ( sp, msg) ;
503
503
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
+ ) ) ;
504
509
err. emit ( ) ;
505
510
}
506
511
_ => {
@@ -511,6 +516,11 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
511
516
for ( sp, msg) in unused_operands {
512
517
err. span_label ( sp, msg) ;
513
518
}
519
+ err. help ( & format ! (
520
+ "if these arguments are intentionally unused, \
521
+ consider using them in an asm comment: `\" /*{} */\" `",
522
+ help_str
523
+ ) ) ;
514
524
err. emit ( ) ;
515
525
}
516
526
}
@@ -521,7 +531,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
521
531
parser. line_spans . iter ( ) . map ( |span| template_span. from_inner ( * span) ) . collect ( )
522
532
} ;
523
533
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 } ;
525
536
P ( ast:: Expr {
526
537
id : ast:: DUMMY_NODE_ID ,
527
538
kind : ast:: ExprKind :: InlineAsm ( P ( inline_asm) ) ,
0 commit comments