@@ -550,17 +550,6 @@ pub fn diag_lint_level<'a, D: Diagnostic<'a, ()> + 'a>(
550550 Level :: Warn => rustc_errors:: Level :: Warning ,
551551 Level :: Deny | Level :: Forbid => rustc_errors:: Level :: Error ,
552552 } ;
553- // Finally, run `decorate`. `decorate` can call `trimmed_path_str` (directly or indirectly),
554- // so we need to make sure when we do call `decorate` that the diagnostic is eventually
555- // emitted or we'll get a `must_produce_diag` ICE.
556- //
557- // When is a diagnostic *eventually* emitted? Well, that is determined by 2 factors:
558- // 1. If the corresponding `rustc_errors::Level` is beyond warning, i.e. `ForceWarning(_)`
559- // or `Error`, then the diagnostic will be emitted regardless of CLI options.
560- // 2. If the corresponding `rustc_errors::Level` is warning, then that can be affected by
561- // `-A warnings` or `--cap-lints=xxx` on the command line. In which case, the diagnostic
562- // will be emitted if `can_emit_warnings` is true.
563- let skip = err_level == rustc_errors:: Level :: Warning && !sess. dcx ( ) . can_emit_warnings ( ) ;
564553
565554 let disable_suggestions = if let Some ( ref span) = span
566555 // If this code originates in a foreign macro, aka something that this crate
@@ -580,12 +569,35 @@ pub fn diag_lint_level<'a, D: Diagnostic<'a, ()> + 'a>(
580569 // allow individual lints to opt-out from being reported.
581570 let incompatible = future_incompatible. is_some_and ( |f| f. reason . edition ( ) . is_none ( ) ) ;
582571
583- if !incompatible && !lint. report_in_external_macro {
572+ // In rustc, for the find_attr macro, we want to always emit this.
573+ // This completely circumvents normal lint checking, which usually doesn't happen for macros from other crates.
574+ // However, we kind of want that when using find_attr from another rustc crate. So we cheat a little.
575+ let is_in_find_attr = sess. enable_internal_lints ( )
576+ && span. as_ref ( ) . is_some_and ( |span| {
577+ span. primary_spans ( ) . iter ( ) . any ( |s| {
578+ s. source_callee ( ) . is_some_and ( |i| {
579+ matches ! ( i. kind, ExpnKind :: Macro ( _, name) if name. as_str( ) == "find_attr" )
580+ } )
581+ } )
582+ } ) ;
583+
584+ if !incompatible && !lint. report_in_external_macro && !is_in_find_attr {
584585 // Don't continue further, since we don't want to have
585586 // `diag_span_note_once` called for a diagnostic that isn't emitted.
586587 return ;
587588 }
588589 }
590+ // Finally, run `decorate`. `decorate` can call `trimmed_path_str` (directly or indirectly),
591+ // so we need to make sure when we do call `decorate` that the diagnostic is eventually
592+ // emitted or we'll get a `must_produce_diag` ICE.
593+ //
594+ // When is a diagnostic *eventually* emitted? Well, that is determined by 2 factors:
595+ // 1. If the corresponding `rustc_errors::Level` is beyond warning, i.e. `ForceWarning(_)`
596+ // or `Error`, then the diagnostic will be emitted regardless of CLI options.
597+ // 2. If the corresponding `rustc_errors::Level` is warning, then that can be affected by
598+ // `-A warnings` or `--cap-lints=xxx` on the command line. In which case, the diagnostic
599+ // will be emitted if `can_emit_warnings` is true.
600+ let skip = err_level == rustc_errors:: Level :: Warning && !sess. dcx ( ) . can_emit_warnings ( ) ;
589601
590602 let mut err: Diag < ' _ , ( ) > = if !skip {
591603 decorate ( sess. dcx ( ) , err_level)
0 commit comments