@@ -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 ;
@@ -461,28 +462,54 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
461462 /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
462463 /// must be delayed until after HIR is built. This method will take care of the details of
463464 /// that.
464- pub ( crate ) fn emit_lint < M : Into < MultiSpan > > (
465+ pub ( crate ) fn emit_lint (
465466 & mut self ,
466467 lint : & ' static Lint ,
467468 kind : AttributeLintKind ,
468- span : M ,
469+ span : impl Into < MultiSpan > ,
470+ ) {
471+ self . emit_lint_inner ( lint, EmitAttribute :: Static ( kind) , span) ;
472+ }
473+
474+ /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
475+ /// must be delayed until after HIR is built. This method will take care of the details of
476+ /// that.
477+ pub ( crate ) fn emit_dyn_lint <
478+ F : for < ' a > Fn ( DiagCtxtHandle < ' a > , Level ) -> Diag < ' a , ( ) > + DynSend + DynSync + ' static ,
479+ > (
480+ & mut self ,
481+ lint : & ' static Lint ,
482+ callback : F ,
483+ span : impl Into < MultiSpan > ,
484+ ) {
485+ self . emit_lint_inner ( lint, EmitAttribute :: Dynamic ( Box :: new ( callback) ) , span) ;
486+ }
487+
488+ fn emit_lint_inner (
489+ & mut self ,
490+ lint : & ' static Lint ,
491+ kind : EmitAttribute ,
492+ span : impl Into < MultiSpan > ,
469493 ) {
470494 if !matches ! (
471495 self . stage. should_emit( ) ,
472496 ShouldEmit :: ErrorsAndLints { .. } | ShouldEmit :: EarlyFatal { also_emit_lints: true }
473497 ) {
474498 return ;
475499 }
476- ( self . emit_lint ) ( LintId :: of ( lint) , span. into ( ) , EmitAttribute :: Static ( kind) ) ;
500+ ( self . emit_lint ) ( LintId :: of ( lint) , span. into ( ) , kind) ;
477501 }
478502
479503 pub ( crate ) fn warn_unused_duplicate ( & mut self , used_span : Span , unused_span : Span ) {
480- self . emit_lint (
504+ self . emit_dyn_lint (
481505 rustc_session:: lint:: builtin:: UNUSED_ATTRIBUTES ,
482- AttributeLintKind :: UnusedDuplicate {
483- this : unused_span,
484- other : used_span,
485- warning : false ,
506+ move |dcx, level| {
507+ rustc_errors:: lints:: UnusedDuplicate {
508+ this : unused_span,
509+ other : used_span,
510+ warning : false ,
511+ }
512+ . into_diag ( dcx, level)
486513 } ,
487514 unused_span,
488515 )
@@ -493,12 +520,15 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
493520 used_span : Span ,
494521 unused_span : Span ,
495522 ) {
496- self . emit_lint (
523+ self . emit_dyn_lint (
497524 rustc_session:: lint:: builtin:: UNUSED_ATTRIBUTES ,
498- AttributeLintKind :: UnusedDuplicate {
499- this : unused_span,
500- other : used_span,
501- warning : true ,
525+ move |dcx, level| {
526+ rustc_errors:: lints:: UnusedDuplicate {
527+ this : unused_span,
528+ other : used_span,
529+ warning : true ,
530+ }
531+ . into_diag ( dcx, level)
502532 } ,
503533 unused_span,
504534 )
0 commit comments