@@ -7,7 +7,8 @@ use std::sync::LazyLock;
77
88use private:: Sealed ;
99use rustc_ast:: { AttrStyle , MetaItemLit , NodeId } ;
10- use rustc_errors:: { Diag , Diagnostic , Level } ;
10+ use rustc_data_structures:: sync:: { DynSend , DynSync } ;
11+ use rustc_errors:: { Diag , DiagCtxtHandle , Diagnostic , Level } ;
1112use rustc_feature:: { AttrSuggestionStyle , AttributeTemplate } ;
1213use rustc_hir:: attrs:: AttributeKind ;
1314use rustc_hir:: lints:: AttributeLintKind ;
@@ -456,22 +457,43 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
456457 /// must be delayed until after HIR is built. This method will take care of the details of
457458 /// that.
458459 pub ( crate ) fn emit_lint ( & mut self , lint : & ' static Lint , kind : AttributeLintKind , span : Span ) {
460+ self . emit_lint_inner ( lint, EmitAttribute :: Static ( kind) , span) ;
461+ }
462+
463+ /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
464+ /// must be delayed until after HIR is built. This method will take care of the details of
465+ /// that.
466+ pub ( crate ) fn emit_dyn_lint <
467+ F : for < ' a > Fn ( DiagCtxtHandle < ' a > , Level ) -> Diag < ' a , ( ) > + DynSend + DynSync + ' static ,
468+ > (
469+ & mut self ,
470+ lint : & ' static Lint ,
471+ callback : F ,
472+ span : Span ,
473+ ) {
474+ self . emit_lint_inner ( lint, EmitAttribute :: Dynamic ( Box :: new ( callback) ) , span) ;
475+ }
476+
477+ fn emit_lint_inner ( & mut self , lint : & ' static Lint , kind : EmitAttribute , span : Span ) {
459478 if !matches ! (
460479 self . stage. should_emit( ) ,
461480 ShouldEmit :: ErrorsAndLints { .. } | ShouldEmit :: EarlyFatal { also_emit_lints: true }
462481 ) {
463482 return ;
464483 }
465- ( self . emit_lint ) ( LintId :: of ( lint) , span, EmitAttribute :: Static ( kind) ) ;
484+ ( self . emit_lint ) ( LintId :: of ( lint) , span, kind) ;
466485 }
467486
468487 pub ( crate ) fn warn_unused_duplicate ( & mut self , used_span : Span , unused_span : Span ) {
469- self . emit_lint (
488+ self . emit_dyn_lint (
470489 rustc_session:: lint:: builtin:: UNUSED_ATTRIBUTES ,
471- AttributeLintKind :: UnusedDuplicate {
472- this : unused_span,
473- other : used_span,
474- warning : false ,
490+ move |dcx, level| {
491+ rustc_errors:: lints:: UnusedDuplicate {
492+ this : unused_span,
493+ other : used_span,
494+ warning : false ,
495+ }
496+ . into_diag ( dcx, level)
475497 } ,
476498 unused_span,
477499 )
@@ -482,12 +504,15 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
482504 used_span : Span ,
483505 unused_span : Span ,
484506 ) {
485- self . emit_lint (
507+ self . emit_dyn_lint (
486508 rustc_session:: lint:: builtin:: UNUSED_ATTRIBUTES ,
487- AttributeLintKind :: UnusedDuplicate {
488- this : unused_span,
489- other : used_span,
490- warning : true ,
509+ move |dcx, level| {
510+ rustc_errors:: lints:: UnusedDuplicate {
511+ this : unused_span,
512+ other : used_span,
513+ warning : true ,
514+ }
515+ . into_diag ( dcx, level)
491516 } ,
492517 unused_span,
493518 )
0 commit comments