@@ -9,6 +9,7 @@ use rustc_hir::def_id::DefId;
9
9
use rustc_middle:: ty:: GenericArgsRef ;
10
10
use rustc_middle:: ty:: { self , GenericParamDefKind , TyCtxt } ;
11
11
use rustc_parse_format:: { ParseMode , Parser , Piece , Position } ;
12
+ use rustc_session:: lint:: builtin:: UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES ;
12
13
use rustc_span:: symbol:: { kw, sym, Symbol } ;
13
14
use rustc_span:: { Span , DUMMY_SP } ;
14
15
use std:: iter;
@@ -336,14 +337,19 @@ pub enum AppendConstMessage {
336
337
Custom ( Symbol ) ,
337
338
}
338
339
340
+ #[ derive( LintDiagnostic ) ]
341
+ #[ diag( trait_selection_malformed_on_unimplemented_attr) ]
342
+ pub struct NoValueInOnUnimplementedLint ;
343
+
339
344
impl < ' tcx > OnUnimplementedDirective {
340
345
fn parse (
341
346
tcx : TyCtxt < ' tcx > ,
342
347
item_def_id : DefId ,
343
348
items : & [ NestedMetaItem ] ,
344
349
span : Span ,
345
350
is_root : bool ,
346
- ) -> Result < Self , ErrorGuaranteed > {
351
+ is_diagnostic_namespace_variant : bool ,
352
+ ) -> Result < Option < Self > , ErrorGuaranteed > {
347
353
let mut errored = None ;
348
354
let mut item_iter = items. iter ( ) ;
349
355
@@ -391,7 +397,10 @@ impl<'tcx> OnUnimplementedDirective {
391
397
note = parse_value ( note_) ?;
392
398
continue ;
393
399
}
394
- } else if item. has_name ( sym:: parent_label) && parent_label. is_none ( ) {
400
+ } else if item. has_name ( sym:: parent_label)
401
+ && parent_label. is_none ( )
402
+ && !is_diagnostic_namespace_variant
403
+ {
395
404
if let Some ( parent_label_) = item. value_str ( ) {
396
405
parent_label = parse_value ( parent_label_) ?;
397
406
continue ;
@@ -401,15 +410,30 @@ impl<'tcx> OnUnimplementedDirective {
401
410
&& message. is_none ( )
402
411
&& label. is_none ( )
403
412
&& note. is_none ( )
413
+ && !is_diagnostic_namespace_variant
414
+ // FIXME(diagnostic_namespace): disallow filters for now
404
415
{
405
416
if let Some ( items) = item. meta_item_list ( ) {
406
- match Self :: parse ( tcx, item_def_id, & items, item. span ( ) , false ) {
407
- Ok ( subcommand) => subcommands. push ( subcommand) ,
417
+ match Self :: parse (
418
+ tcx,
419
+ item_def_id,
420
+ & items,
421
+ item. span ( ) ,
422
+ false ,
423
+ is_diagnostic_namespace_variant,
424
+ ) {
425
+ Ok ( Some ( subcommand) ) => subcommands. push ( subcommand) ,
426
+ Ok ( None ) => bug ! (
427
+ "This cannot happen for now as we only reach that if `is_diagnostic_namespace_variant` is false"
428
+ ) ,
408
429
Err ( reported) => errored = Some ( reported) ,
409
430
} ;
410
431
continue ;
411
432
}
412
- } else if item. has_name ( sym:: append_const_msg) && append_const_msg. is_none ( ) {
433
+ } else if item. has_name ( sym:: append_const_msg)
434
+ && append_const_msg. is_none ( )
435
+ && !is_diagnostic_namespace_variant
436
+ {
413
437
if let Some ( msg) = item. value_str ( ) {
414
438
append_const_msg = Some ( AppendConstMessage :: Custom ( msg) ) ;
415
439
continue ;
@@ -419,47 +443,82 @@ impl<'tcx> OnUnimplementedDirective {
419
443
}
420
444
}
421
445
422
- // nothing found
423
- tcx. sess . emit_err ( NoValueInOnUnimplemented { span : item. span ( ) } ) ;
446
+ if is_diagnostic_namespace_variant {
447
+ tcx. emit_spanned_lint (
448
+ UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES ,
449
+ tcx. hir ( ) . local_def_id_to_hir_id ( item_def_id. expect_local ( ) ) ,
450
+ vec ! [ item. span( ) ] ,
451
+ NoValueInOnUnimplementedLint ,
452
+ ) ;
453
+ } else {
454
+ // nothing found
455
+ tcx. sess . emit_err ( NoValueInOnUnimplemented { span : item. span ( ) } ) ;
456
+ }
424
457
}
425
458
426
459
if let Some ( reported) = errored {
427
- Err ( reported)
460
+ if is_diagnostic_namespace_variant { Ok ( None ) } else { Err ( reported) }
428
461
} else {
429
- Ok ( OnUnimplementedDirective {
462
+ Ok ( Some ( OnUnimplementedDirective {
430
463
condition,
431
464
subcommands,
432
465
message,
433
466
label,
434
467
note,
435
468
parent_label,
436
469
append_const_msg,
437
- } )
470
+ } ) )
438
471
}
439
472
}
440
473
441
474
pub fn of_item ( tcx : TyCtxt < ' tcx > , item_def_id : DefId ) -> Result < Option < Self > , ErrorGuaranteed > {
442
- let Some ( attr) = tcx. get_attr ( item_def_id, sym:: rustc_on_unimplemented) else {
475
+ let mut is_diagnostic_namespace_variant = false ;
476
+ let Some ( attr) = tcx. get_attr ( item_def_id, sym:: rustc_on_unimplemented) . or_else ( || {
477
+ if tcx. features ( ) . diagnostic_namespace {
478
+ is_diagnostic_namespace_variant = true ;
479
+ tcx. get_attrs_by_path ( item_def_id, & [ sym:: diagnostic, sym:: on_unimplemented] ) . next ( )
480
+ } else {
481
+ None
482
+ }
483
+ } ) else {
443
484
return Ok ( None ) ;
444
485
} ;
445
486
446
487
let result = if let Some ( items) = attr. meta_item_list ( ) {
447
- Self :: parse ( tcx, item_def_id, & items, attr. span , true ) . map ( Some )
488
+ Self :: parse ( tcx, item_def_id, & items, attr. span , true , is_diagnostic_namespace_variant )
448
489
} else if let Some ( value) = attr. value_str ( ) {
449
- Ok ( Some ( OnUnimplementedDirective {
450
- condition : None ,
451
- message : None ,
452
- subcommands : vec ! [ ] ,
453
- label : Some ( OnUnimplementedFormatString :: try_parse (
454
- tcx,
455
- item_def_id,
456
- value,
490
+ if !is_diagnostic_namespace_variant {
491
+ Ok ( Some ( OnUnimplementedDirective {
492
+ condition : None ,
493
+ message : None ,
494
+ subcommands : vec ! [ ] ,
495
+ label : Some ( OnUnimplementedFormatString :: try_parse (
496
+ tcx,
497
+ item_def_id,
498
+ value,
499
+ attr. span ,
500
+ ) ?) ,
501
+ note : None ,
502
+ parent_label : None ,
503
+ append_const_msg : None ,
504
+ } ) )
505
+ } else {
506
+ tcx. emit_spanned_lint (
507
+ UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES ,
508
+ tcx. hir ( ) . local_def_id_to_hir_id ( item_def_id. expect_local ( ) ) ,
457
509
attr. span ,
458
- ) ?) ,
459
- note : None ,
460
- parent_label : None ,
461
- append_const_msg : None ,
462
- } ) )
510
+ NoValueInOnUnimplementedLint ,
511
+ ) ;
512
+ Ok ( None )
513
+ }
514
+ } else if is_diagnostic_namespace_variant {
515
+ tcx. emit_spanned_lint (
516
+ UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES ,
517
+ tcx. hir ( ) . local_def_id_to_hir_id ( item_def_id. expect_local ( ) ) ,
518
+ attr. span ,
519
+ NoValueInOnUnimplementedLint ,
520
+ ) ;
521
+ Ok ( None )
463
522
} else {
464
523
let reported =
465
524
tcx. sess . delay_span_bug ( DUMMY_SP , "of_item: neither meta_item_list nor value_str" ) ;
0 commit comments