@@ -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 , MultiSpan } ;
10+ use rustc_data_structures:: sync:: { DynSend , DynSync } ;
11+ use rustc_errors:: { Diag , DiagCtxtHandle , Diagnostic , Level , MultiSpan } ;
1112use rustc_feature:: { AttrSuggestionStyle , AttributeTemplate } ;
1213use rustc_hir:: attrs:: AttributeKind ;
1314use rustc_hir:: lints:: AttributeLintKind ;
@@ -458,28 +459,54 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
458459 /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
459460 /// must be delayed until after HIR is built. This method will take care of the details of
460461 /// that.
461- pub ( crate ) fn emit_lint < M : Into < MultiSpan > > (
462+ pub ( crate ) fn emit_lint (
462463 & mut self ,
463464 lint : & ' static Lint ,
464465 kind : AttributeLintKind ,
465- span : M ,
466+ span : impl Into < MultiSpan > ,
467+ ) {
468+ self . emit_lint_inner ( lint, EmitAttribute :: Static ( kind) , span) ;
469+ }
470+
471+ /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
472+ /// must be delayed until after HIR is built. This method will take care of the details of
473+ /// that.
474+ pub ( crate ) fn emit_dyn_lint <
475+ F : for < ' a > Fn ( DiagCtxtHandle < ' a > , Level ) -> Diag < ' a , ( ) > + DynSend + DynSync + ' static ,
476+ > (
477+ & mut self ,
478+ lint : & ' static Lint ,
479+ callback : F ,
480+ span : impl Into < MultiSpan > ,
481+ ) {
482+ self . emit_lint_inner ( lint, EmitAttribute :: Dynamic ( Box :: new ( callback) ) , span) ;
483+ }
484+
485+ fn emit_lint_inner (
486+ & mut self ,
487+ lint : & ' static Lint ,
488+ kind : EmitAttribute ,
489+ span : impl Into < MultiSpan > ,
466490 ) {
467491 if !matches ! (
468492 self . stage. should_emit( ) ,
469493 ShouldEmit :: ErrorsAndLints { .. } | ShouldEmit :: EarlyFatal { also_emit_lints: true }
470494 ) {
471495 return ;
472496 }
473- ( self . emit_lint ) ( LintId :: of ( lint) , span. into ( ) , EmitAttribute :: Static ( kind) ) ;
497+ ( self . emit_lint ) ( LintId :: of ( lint) , span. into ( ) , kind) ;
474498 }
475499
476500 pub ( crate ) fn warn_unused_duplicate ( & mut self , used_span : Span , unused_span : Span ) {
477- self . emit_lint (
501+ self . emit_dyn_lint (
478502 rustc_session:: lint:: builtin:: UNUSED_ATTRIBUTES ,
479- AttributeLintKind :: UnusedDuplicate {
480- this : unused_span,
481- other : used_span,
482- warning : false ,
503+ move |dcx, level| {
504+ rustc_errors:: lints:: UnusedDuplicate {
505+ this : unused_span,
506+ other : used_span,
507+ warning : false ,
508+ }
509+ . into_diag ( dcx, level)
483510 } ,
484511 unused_span,
485512 )
@@ -490,12 +517,15 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
490517 used_span : Span ,
491518 unused_span : Span ,
492519 ) {
493- self . emit_lint (
520+ self . emit_dyn_lint (
494521 rustc_session:: lint:: builtin:: UNUSED_ATTRIBUTES ,
495- AttributeLintKind :: UnusedDuplicate {
496- this : unused_span,
497- other : used_span,
498- warning : true ,
522+ move |dcx, level| {
523+ rustc_errors:: lints:: UnusedDuplicate {
524+ this : unused_span,
525+ other : used_span,
526+ warning : true ,
527+ }
528+ . into_diag ( dcx, level)
499529 } ,
500530 unused_span,
501531 )
0 commit comments