@@ -6,7 +6,8 @@ use std::sync::LazyLock;
66
77use private:: Sealed ;
88use rustc_ast:: { AttrStyle , MetaItemLit , NodeId } ;
9- use rustc_errors:: { Diag , Diagnostic , Level } ;
9+ use rustc_data_structures:: sync:: { DynSend , DynSync } ;
10+ use rustc_errors:: { Diag , DiagCtxtHandle , Diagnostic , Level } ;
1011use rustc_feature:: { AttrSuggestionStyle , AttributeTemplate } ;
1112use rustc_hir:: attrs:: AttributeKind ;
1213use rustc_hir:: lints:: AttributeLintKind ;
@@ -448,22 +449,43 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
448449 /// must be delayed until after HIR is built. This method will take care of the details of
449450 /// that.
450451 pub ( crate ) fn emit_lint ( & mut self , lint : & ' static Lint , kind : AttributeLintKind , span : Span ) {
452+ self . emit_lint_inner ( lint, EmitAttribute :: Static ( kind) , span) ;
453+ }
454+
455+ /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
456+ /// must be delayed until after HIR is built. This method will take care of the details of
457+ /// that.
458+ pub ( crate ) fn emit_dyn_lint <
459+ F : for < ' a > Fn ( DiagCtxtHandle < ' a > , Level ) -> Diag < ' a , ( ) > + DynSend + DynSync + ' static ,
460+ > (
461+ & mut self ,
462+ lint : & ' static Lint ,
463+ callback : F ,
464+ span : Span ,
465+ ) {
466+ self . emit_lint_inner ( lint, EmitAttribute :: Dynamic ( Box :: new ( callback) ) , span) ;
467+ }
468+
469+ fn emit_lint_inner ( & mut self , lint : & ' static Lint , kind : EmitAttribute , span : Span ) {
451470 if !matches ! (
452471 self . stage. should_emit( ) ,
453472 ShouldEmit :: ErrorsAndLints { .. } | ShouldEmit :: EarlyFatal { also_emit_lints: true }
454473 ) {
455474 return ;
456475 }
457- ( self . emit_lint ) ( LintId :: of ( lint) , span, EmitAttribute :: Static ( kind) ) ;
476+ ( self . emit_lint ) ( LintId :: of ( lint) , span, kind) ;
458477 }
459478
460479 pub ( crate ) fn warn_unused_duplicate ( & mut self , used_span : Span , unused_span : Span ) {
461- self . emit_lint (
480+ self . emit_dyn_lint (
462481 rustc_session:: lint:: builtin:: UNUSED_ATTRIBUTES ,
463- AttributeLintKind :: UnusedDuplicate {
464- this : unused_span,
465- other : used_span,
466- warning : false ,
482+ move |dcx, level| {
483+ rustc_errors:: lints:: UnusedDuplicate {
484+ this : unused_span,
485+ other : used_span,
486+ warning : false ,
487+ }
488+ . into_diag ( dcx, level)
467489 } ,
468490 unused_span,
469491 )
@@ -474,12 +496,15 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
474496 used_span : Span ,
475497 unused_span : Span ,
476498 ) {
477- self . emit_lint (
499+ self . emit_dyn_lint (
478500 rustc_session:: lint:: builtin:: UNUSED_ATTRIBUTES ,
479- AttributeLintKind :: UnusedDuplicate {
480- this : unused_span,
481- other : used_span,
482- warning : true ,
501+ move |dcx, level| {
502+ rustc_errors:: lints:: UnusedDuplicate {
503+ this : unused_span,
504+ other : used_span,
505+ warning : true ,
506+ }
507+ . into_diag ( dcx, level)
483508 } ,
484509 unused_span,
485510 )
0 commit comments