@@ -325,7 +325,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
325
325
}
326
326
327
327
#[ derive( Clone , Debug ) ]
328
- pub struct OnUnimplementedFormatString ( Symbol ) ;
328
+ pub struct OnUnimplementedFormatString ( Symbol , Span ) ;
329
329
330
330
#[ derive( Debug ) ]
331
331
pub struct OnUnimplementedDirective {
@@ -354,7 +354,7 @@ pub struct OnUnimplementedNote {
354
354
pub enum AppendConstMessage {
355
355
#[ default]
356
356
Default ,
357
- Custom ( Symbol ) ,
357
+ Custom ( Symbol , Span ) ,
358
358
}
359
359
360
360
#[ derive( LintDiagnostic ) ]
@@ -376,6 +376,35 @@ impl MalformedOnUnimplementedAttrLint {
376
376
#[ help]
377
377
pub struct MissingOptionsForOnUnimplementedAttr ;
378
378
379
+ #[ derive( LintDiagnostic ) ]
380
+ #[ diag( trait_selection_ignored_diagnostic_option) ]
381
+ pub struct IgnoredDiagnosticOption {
382
+ pub option_name : & ' static str ,
383
+ #[ label]
384
+ pub span : Span ,
385
+ #[ label( trait_selection_other_label) ]
386
+ pub prev_span : Span ,
387
+ }
388
+
389
+ impl IgnoredDiagnosticOption {
390
+ fn maybe_emit_warning < ' tcx > (
391
+ tcx : TyCtxt < ' tcx > ,
392
+ item_def_id : DefId ,
393
+ new : Option < Span > ,
394
+ old : Option < Span > ,
395
+ option_name : & ' static str ,
396
+ ) {
397
+ if let ( Some ( new_item) , Some ( old_item) ) = ( new, old) {
398
+ tcx. emit_spanned_lint (
399
+ UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES ,
400
+ tcx. hir ( ) . local_def_id_to_hir_id ( item_def_id. expect_local ( ) ) ,
401
+ new_item,
402
+ IgnoredDiagnosticOption { span : new_item, prev_span : old_item, option_name } ,
403
+ ) ;
404
+ }
405
+ }
406
+ }
407
+
379
408
impl < ' tcx > OnUnimplementedDirective {
380
409
fn parse (
381
410
tcx : TyCtxt < ' tcx > ,
@@ -388,8 +417,9 @@ impl<'tcx> OnUnimplementedDirective {
388
417
let mut errored = None ;
389
418
let mut item_iter = items. iter ( ) ;
390
419
391
- let parse_value = |value_str| {
392
- OnUnimplementedFormatString :: try_parse ( tcx, item_def_id, value_str, span) . map ( Some )
420
+ let parse_value = |value_str, value_span| {
421
+ OnUnimplementedFormatString :: try_parse ( tcx, item_def_id, value_str, span, value_span)
422
+ . map ( Some )
393
423
} ;
394
424
395
425
let condition = if is_root {
@@ -402,7 +432,7 @@ impl<'tcx> OnUnimplementedDirective {
402
432
. ok_or_else ( || tcx. sess . emit_err ( InvalidOnClauseInOnUnimplemented { span } ) ) ?;
403
433
attr:: eval_condition ( cond, & tcx. sess . parse_sess , Some ( tcx. features ( ) ) , & mut |cfg| {
404
434
if let Some ( value) = cfg. value
405
- && let Err ( guar) = parse_value ( value)
435
+ && let Err ( guar) = parse_value ( value, cfg . span )
406
436
{
407
437
errored = Some ( guar) ;
408
438
}
@@ -421,17 +451,17 @@ impl<'tcx> OnUnimplementedDirective {
421
451
for item in item_iter {
422
452
if item. has_name ( sym:: message) && message. is_none ( ) {
423
453
if let Some ( message_) = item. value_str ( ) {
424
- message = parse_value ( message_) ?;
454
+ message = parse_value ( message_, item . span ( ) ) ?;
425
455
continue ;
426
456
}
427
457
} else if item. has_name ( sym:: label) && label. is_none ( ) {
428
458
if let Some ( label_) = item. value_str ( ) {
429
- label = parse_value ( label_) ?;
459
+ label = parse_value ( label_, item . span ( ) ) ?;
430
460
continue ;
431
461
}
432
462
} else if item. has_name ( sym:: note) {
433
463
if let Some ( note_) = item. value_str ( ) {
434
- if let Some ( note) = parse_value ( note_) ? {
464
+ if let Some ( note) = parse_value ( note_, item . span ( ) ) ? {
435
465
notes. push ( note) ;
436
466
continue ;
437
467
}
@@ -441,7 +471,7 @@ impl<'tcx> OnUnimplementedDirective {
441
471
&& !is_diagnostic_namespace_variant
442
472
{
443
473
if let Some ( parent_label_) = item. value_str ( ) {
444
- parent_label = parse_value ( parent_label_) ?;
474
+ parent_label = parse_value ( parent_label_, item . span ( ) ) ?;
445
475
continue ;
446
476
}
447
477
} else if item. has_name ( sym:: on)
@@ -474,7 +504,7 @@ impl<'tcx> OnUnimplementedDirective {
474
504
&& !is_diagnostic_namespace_variant
475
505
{
476
506
if let Some ( msg) = item. value_str ( ) {
477
- append_const_msg = Some ( AppendConstMessage :: Custom ( msg) ) ;
507
+ append_const_msg = Some ( AppendConstMessage :: Custom ( msg, item . span ( ) ) ) ;
478
508
continue ;
479
509
} else if item. is_word ( ) {
480
510
append_const_msg = Some ( AppendConstMessage :: Default ) ;
@@ -523,6 +553,54 @@ impl<'tcx> OnUnimplementedDirective {
523
553
subcommands. extend ( directive. subcommands ) ;
524
554
let mut notes = aggr. notes ;
525
555
notes. extend ( directive. notes ) ;
556
+ IgnoredDiagnosticOption :: maybe_emit_warning (
557
+ tcx,
558
+ item_def_id,
559
+ directive. message . as_ref ( ) . map ( |f| f. 1 ) ,
560
+ aggr. message . as_ref ( ) . map ( |f| f. 1 ) ,
561
+ "message" ,
562
+ ) ;
563
+ IgnoredDiagnosticOption :: maybe_emit_warning (
564
+ tcx,
565
+ item_def_id,
566
+ directive. label . as_ref ( ) . map ( |f| f. 1 ) ,
567
+ aggr. label . as_ref ( ) . map ( |f| f. 1 ) ,
568
+ "label" ,
569
+ ) ;
570
+ IgnoredDiagnosticOption :: maybe_emit_warning (
571
+ tcx,
572
+ item_def_id,
573
+ directive. condition . as_ref ( ) . map ( |i| i. span ) ,
574
+ aggr. condition . as_ref ( ) . map ( |i| i. span ) ,
575
+ "condition" ,
576
+ ) ;
577
+ IgnoredDiagnosticOption :: maybe_emit_warning (
578
+ tcx,
579
+ item_def_id,
580
+ directive. parent_label . as_ref ( ) . map ( |f| f. 1 ) ,
581
+ aggr. parent_label . as_ref ( ) . map ( |f| f. 1 ) ,
582
+ "parent_label" ,
583
+ ) ;
584
+ IgnoredDiagnosticOption :: maybe_emit_warning (
585
+ tcx,
586
+ item_def_id,
587
+ directive. append_const_msg . as_ref ( ) . and_then ( |c| {
588
+ if let AppendConstMessage :: Custom ( _, s) = c {
589
+ Some ( * s)
590
+ } else {
591
+ None
592
+ }
593
+ } ) ,
594
+ aggr. append_const_msg . as_ref ( ) . and_then ( |c| {
595
+ if let AppendConstMessage :: Custom ( _, s) = c {
596
+ Some ( * s)
597
+ } else {
598
+ None
599
+ }
600
+ } ) ,
601
+ "append_const_msg" ,
602
+ ) ;
603
+
526
604
Ok ( Some ( Self {
527
605
condition : aggr. condition . or ( directive. condition ) ,
528
606
subcommands,
@@ -560,6 +638,7 @@ impl<'tcx> OnUnimplementedDirective {
560
638
item_def_id,
561
639
value,
562
640
attr. span ,
641
+ attr. span ,
563
642
) ?) ,
564
643
notes : Vec :: new ( ) ,
565
644
parent_label : None ,
@@ -636,7 +715,7 @@ impl<'tcx> OnUnimplementedDirective {
636
715
let value = cfg. value . map ( |v| {
637
716
// `with_no_visible_paths` is also used when generating the options,
638
717
// so we need to match it here.
639
- ty:: print:: with_no_visible_paths!( OnUnimplementedFormatString ( v) . format( tcx, trait_ref, & options_map) )
718
+ ty:: print:: with_no_visible_paths!( OnUnimplementedFormatString ( v, cfg . span ) . format( tcx, trait_ref, & options_map) )
640
719
} ) ;
641
720
642
721
options. contains ( & ( cfg. name , value) )
@@ -680,8 +759,9 @@ impl<'tcx> OnUnimplementedFormatString {
680
759
item_def_id : DefId ,
681
760
from : Symbol ,
682
761
err_sp : Span ,
762
+ value_span : Span ,
683
763
) -> Result < Self , ErrorGuaranteed > {
684
- let result = OnUnimplementedFormatString ( from) ;
764
+ let result = OnUnimplementedFormatString ( from, value_span ) ;
685
765
result. verify ( tcx, item_def_id, err_sp) ?;
686
766
Ok ( result)
687
767
}
0 commit comments