@@ -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 ;
@@ -460,22 +461,43 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
460461 /// must be delayed until after HIR is built. This method will take care of the details of
461462 /// that.
462463 pub ( crate ) fn emit_lint ( & mut self , lint : & ' static Lint , kind : AttributeLintKind , span : Span ) {
464+ self . emit_lint_inner ( lint, EmitAttribute :: Static ( kind) , span) ;
465+ }
466+
467+ /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
468+ /// must be delayed until after HIR is built. This method will take care of the details of
469+ /// that.
470+ pub ( crate ) fn emit_dyn_lint <
471+ F : for < ' a > Fn ( DiagCtxtHandle < ' a > , Level ) -> Diag < ' a , ( ) > + DynSend + DynSync + ' static ,
472+ > (
473+ & mut self ,
474+ lint : & ' static Lint ,
475+ callback : F ,
476+ span : Span ,
477+ ) {
478+ self . emit_lint_inner ( lint, EmitAttribute :: Dynamic ( Box :: new ( callback) ) , span) ;
479+ }
480+
481+ fn emit_lint_inner ( & mut self , lint : & ' static Lint , kind : EmitAttribute , span : Span ) {
463482 if !matches ! (
464483 self . stage. should_emit( ) ,
465484 ShouldEmit :: ErrorsAndLints { .. } | ShouldEmit :: EarlyFatal { also_emit_lints: true }
466485 ) {
467486 return ;
468487 }
469- ( self . emit_lint ) ( LintId :: of ( lint) , span, EmitAttribute :: Static ( kind) ) ;
488+ ( self . emit_lint ) ( LintId :: of ( lint) , span, kind) ;
470489 }
471490
472491 pub ( crate ) fn warn_unused_duplicate ( & mut self , used_span : Span , unused_span : Span ) {
473- self . emit_lint (
492+ self . emit_dyn_lint (
474493 rustc_session:: lint:: builtin:: UNUSED_ATTRIBUTES ,
475- AttributeLintKind :: UnusedDuplicate {
476- this : unused_span,
477- other : used_span,
478- warning : false ,
494+ move |dcx, level| {
495+ rustc_errors:: lints:: UnusedDuplicate {
496+ this : unused_span,
497+ other : used_span,
498+ warning : false ,
499+ }
500+ . into_diag ( dcx, level)
479501 } ,
480502 unused_span,
481503 )
@@ -486,12 +508,15 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
486508 used_span : Span ,
487509 unused_span : Span ,
488510 ) {
489- self . emit_lint (
511+ self . emit_dyn_lint (
490512 rustc_session:: lint:: builtin:: UNUSED_ATTRIBUTES ,
491- AttributeLintKind :: UnusedDuplicate {
492- this : unused_span,
493- other : used_span,
494- warning : true ,
513+ move |dcx, level| {
514+ rustc_errors:: lints:: UnusedDuplicate {
515+ this : unused_span,
516+ other : used_span,
517+ warning : true ,
518+ }
519+ . into_diag ( dcx, level)
495520 } ,
496521 unused_span,
497522 )
0 commit comments