@@ -321,7 +321,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
321
321
}
322
322
323
323
#[ derive( Clone , Debug ) ]
324
- pub struct OnUnimplementedFormatString ( Symbol ) ;
324
+ pub struct OnUnimplementedFormatString ( Symbol , Span ) ;
325
325
326
326
#[ derive( Debug ) ]
327
327
pub struct OnUnimplementedDirective {
@@ -350,7 +350,7 @@ pub struct OnUnimplementedNote {
350
350
pub enum AppendConstMessage {
351
351
#[ default]
352
352
Default ,
353
- Custom ( Symbol ) ,
353
+ Custom ( Symbol , Span ) ,
354
354
}
355
355
356
356
#[ derive( LintDiagnostic ) ]
@@ -372,6 +372,35 @@ impl MalformedOnUnimplementedAttrLint {
372
372
#[ help]
373
373
pub struct MissingOptionsForOnUnimplementedAttr ;
374
374
375
+ #[ derive( LintDiagnostic ) ]
376
+ #[ diag( trait_selection_ignored_diagnostic_option) ]
377
+ pub struct IgnoredDiagnosticOption {
378
+ pub option_name : & ' static str ,
379
+ #[ label]
380
+ pub span : Span ,
381
+ #[ label( trait_selection_other_label) ]
382
+ pub prev_span : Span ,
383
+ }
384
+
385
+ impl IgnoredDiagnosticOption {
386
+ fn maybe_emit_warning < ' tcx > (
387
+ tcx : TyCtxt < ' tcx > ,
388
+ item_def_id : DefId ,
389
+ new : Option < Span > ,
390
+ old : Option < Span > ,
391
+ option_name : & ' static str ,
392
+ ) {
393
+ if let ( Some ( new_item) , Some ( old_item) ) = ( new, old) {
394
+ tcx. emit_spanned_lint (
395
+ UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES ,
396
+ tcx. hir ( ) . local_def_id_to_hir_id ( item_def_id. expect_local ( ) ) ,
397
+ new_item,
398
+ IgnoredDiagnosticOption { span : new_item, prev_span : old_item, option_name } ,
399
+ ) ;
400
+ }
401
+ }
402
+ }
403
+
375
404
impl < ' tcx > OnUnimplementedDirective {
376
405
fn parse (
377
406
tcx : TyCtxt < ' tcx > ,
@@ -384,8 +413,9 @@ impl<'tcx> OnUnimplementedDirective {
384
413
let mut errored = None ;
385
414
let mut item_iter = items. iter ( ) ;
386
415
387
- let parse_value = |value_str| {
388
- OnUnimplementedFormatString :: try_parse ( tcx, item_def_id, value_str, span) . map ( Some )
416
+ let parse_value = |value_str, value_span| {
417
+ OnUnimplementedFormatString :: try_parse ( tcx, item_def_id, value_str, span, value_span)
418
+ . map ( Some )
389
419
} ;
390
420
391
421
let condition = if is_root {
@@ -398,7 +428,7 @@ impl<'tcx> OnUnimplementedDirective {
398
428
. ok_or_else ( || tcx. sess . emit_err ( InvalidOnClauseInOnUnimplemented { span } ) ) ?;
399
429
attr:: eval_condition ( cond, & tcx. sess . parse_sess , Some ( tcx. features ( ) ) , & mut |cfg| {
400
430
if let Some ( value) = cfg. value
401
- && let Err ( guar) = parse_value ( value)
431
+ && let Err ( guar) = parse_value ( value, cfg . span )
402
432
{
403
433
errored = Some ( guar) ;
404
434
}
@@ -417,17 +447,17 @@ impl<'tcx> OnUnimplementedDirective {
417
447
for item in item_iter {
418
448
if item. has_name ( sym:: message) && message. is_none ( ) {
419
449
if let Some ( message_) = item. value_str ( ) {
420
- message = parse_value ( message_) ?;
450
+ message = parse_value ( message_, item . span ( ) ) ?;
421
451
continue ;
422
452
}
423
453
} else if item. has_name ( sym:: label) && label. is_none ( ) {
424
454
if let Some ( label_) = item. value_str ( ) {
425
- label = parse_value ( label_) ?;
455
+ label = parse_value ( label_, item . span ( ) ) ?;
426
456
continue ;
427
457
}
428
458
} else if item. has_name ( sym:: note) {
429
459
if let Some ( note_) = item. value_str ( ) {
430
- if let Some ( note) = parse_value ( note_) ? {
460
+ if let Some ( note) = parse_value ( note_, item . span ( ) ) ? {
431
461
notes. push ( note) ;
432
462
continue ;
433
463
}
@@ -437,7 +467,7 @@ impl<'tcx> OnUnimplementedDirective {
437
467
&& !is_diagnostic_namespace_variant
438
468
{
439
469
if let Some ( parent_label_) = item. value_str ( ) {
440
- parent_label = parse_value ( parent_label_) ?;
470
+ parent_label = parse_value ( parent_label_, item . span ( ) ) ?;
441
471
continue ;
442
472
}
443
473
} else if item. has_name ( sym:: on)
@@ -470,7 +500,7 @@ impl<'tcx> OnUnimplementedDirective {
470
500
&& !is_diagnostic_namespace_variant
471
501
{
472
502
if let Some ( msg) = item. value_str ( ) {
473
- append_const_msg = Some ( AppendConstMessage :: Custom ( msg) ) ;
503
+ append_const_msg = Some ( AppendConstMessage :: Custom ( msg, item . span ( ) ) ) ;
474
504
continue ;
475
505
} else if item. is_word ( ) {
476
506
append_const_msg = Some ( AppendConstMessage :: Default ) ;
@@ -519,6 +549,54 @@ impl<'tcx> OnUnimplementedDirective {
519
549
subcommands. extend ( directive. subcommands ) ;
520
550
let mut notes = aggr. notes ;
521
551
notes. extend ( directive. notes ) ;
552
+ IgnoredDiagnosticOption :: maybe_emit_warning (
553
+ tcx,
554
+ item_def_id,
555
+ directive. message . as_ref ( ) . map ( |f| f. 1 ) ,
556
+ aggr. message . as_ref ( ) . map ( |f| f. 1 ) ,
557
+ "message" ,
558
+ ) ;
559
+ IgnoredDiagnosticOption :: maybe_emit_warning (
560
+ tcx,
561
+ item_def_id,
562
+ directive. label . as_ref ( ) . map ( |f| f. 1 ) ,
563
+ aggr. label . as_ref ( ) . map ( |f| f. 1 ) ,
564
+ "label" ,
565
+ ) ;
566
+ IgnoredDiagnosticOption :: maybe_emit_warning (
567
+ tcx,
568
+ item_def_id,
569
+ directive. condition . as_ref ( ) . map ( |i| i. span ) ,
570
+ aggr. condition . as_ref ( ) . map ( |i| i. span ) ,
571
+ "condition" ,
572
+ ) ;
573
+ IgnoredDiagnosticOption :: maybe_emit_warning (
574
+ tcx,
575
+ item_def_id,
576
+ directive. parent_label . as_ref ( ) . map ( |f| f. 1 ) ,
577
+ aggr. parent_label . as_ref ( ) . map ( |f| f. 1 ) ,
578
+ "parent_label" ,
579
+ ) ;
580
+ IgnoredDiagnosticOption :: maybe_emit_warning (
581
+ tcx,
582
+ item_def_id,
583
+ directive. append_const_msg . as_ref ( ) . and_then ( |c| {
584
+ if let AppendConstMessage :: Custom ( _, s) = c {
585
+ Some ( * s)
586
+ } else {
587
+ None
588
+ }
589
+ } ) ,
590
+ aggr. append_const_msg . as_ref ( ) . and_then ( |c| {
591
+ if let AppendConstMessage :: Custom ( _, s) = c {
592
+ Some ( * s)
593
+ } else {
594
+ None
595
+ }
596
+ } ) ,
597
+ "append_const_msg" ,
598
+ ) ;
599
+
522
600
Ok ( Some ( Self {
523
601
condition : aggr. condition . or ( directive. condition ) ,
524
602
subcommands,
@@ -556,6 +634,7 @@ impl<'tcx> OnUnimplementedDirective {
556
634
item_def_id,
557
635
value,
558
636
attr. span ,
637
+ attr. span ,
559
638
) ?) ,
560
639
notes : Vec :: new ( ) ,
561
640
parent_label : None ,
@@ -633,7 +712,11 @@ impl<'tcx> OnUnimplementedDirective {
633
712
// `with_no_visible_paths` is also used when generating the options,
634
713
// so we need to match it here.
635
714
ty:: print:: with_no_visible_paths!(
636
- OnUnimplementedFormatString ( v) . format( tcx, trait_ref, & options_map)
715
+ OnUnimplementedFormatString ( v, cfg. span) . format(
716
+ tcx,
717
+ trait_ref,
718
+ & options_map
719
+ )
637
720
)
638
721
} ) ;
639
722
@@ -678,8 +761,9 @@ impl<'tcx> OnUnimplementedFormatString {
678
761
item_def_id : DefId ,
679
762
from : Symbol ,
680
763
err_sp : Span ,
764
+ value_span : Span ,
681
765
) -> Result < Self , ErrorGuaranteed > {
682
- let result = OnUnimplementedFormatString ( from) ;
766
+ let result = OnUnimplementedFormatString ( from, value_span ) ;
683
767
result. verify ( tcx, item_def_id, err_sp) ?;
684
768
Ok ( result)
685
769
}
0 commit comments