@@ -15,7 +15,7 @@ use rustc_ast_pretty::pprust;
1515use rustc_attr:: StabilityLevel ;
1616use rustc_data_structures:: intern:: Interned ;
1717use rustc_data_structures:: sync:: Lrc ;
18- use rustc_errors:: { struct_span_err, Applicability } ;
18+ use rustc_errors:: { struct_span_err, Applicability , FatalError } ;
1919use rustc_expand:: base:: { Annotatable , DeriveResolutions , Indeterminate , ResolverExpand } ;
2020use rustc_expand:: base:: { SyntaxExtension , SyntaxExtensionKind } ;
2121use rustc_expand:: compile_declarative_macro;
@@ -373,6 +373,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
373373 match self . resolve_macro_path (
374374 path,
375375 Some ( MacroKind :: Derive ) ,
376+ false ,
376377 & parent_scope,
377378 true ,
378379 force,
@@ -504,8 +505,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
504505 force : bool ,
505506 soft_custom_inner_attributes_gate : bool ,
506507 ) -> Result < ( Lrc < SyntaxExtension > , Res ) , Indeterminate > {
507- let ( ext, res) = match self . resolve_macro_path ( path, Some ( kind) , parent_scope, true , force)
508- {
508+ let ( ext, res) = match self . resolve_macro_path (
509+ path,
510+ Some ( kind) ,
511+ inner_attr,
512+ parent_scope,
513+ true ,
514+ force,
515+ ) {
509516 Ok ( ( Some ( ext) , res) ) => ( ext, res) ,
510517 Ok ( ( None , res) ) => ( self . dummy_ext ( kind) , res) ,
511518 Err ( Determinacy :: Determined ) => ( self . dummy_ext ( kind) , Res :: Err ) ,
@@ -627,6 +634,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
627634 & mut self ,
628635 path : & ast:: Path ,
629636 kind : Option < MacroKind > ,
637+ inner_attr : bool ,
630638 parent_scope : & ParentScope < ' a > ,
631639 trace : bool ,
632640 force : bool ,
@@ -685,6 +693,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
685693 self . single_segment_macro_resolutions . push ( (
686694 path[ 0 ] . ident ,
687695 kind,
696+ inner_attr,
688697 * parent_scope,
689698 binding. ok ( ) ,
690699 ) ) ;
@@ -794,7 +803,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
794803 }
795804
796805 let macro_resolutions = mem:: take ( & mut self . single_segment_macro_resolutions ) ;
797- for ( ident, kind, parent_scope, initial_binding) in macro_resolutions {
806+ let mut has_reported_inner_attr_error = false ;
807+ let mut raise_fatal_error = false ;
808+ for ( ident, kind, inner_attr, parent_scope, initial_binding) in macro_resolutions {
798809 match self . early_resolve_ident_in_lexical_scope (
799810 ident,
800811 ScopeSet :: Macro ( kind) ,
@@ -810,7 +821,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
810821 } ) ;
811822 let res = binding. res ( ) ;
812823 let seg = Segment :: from_ident ( ident) ;
813- check_consistency ( self , & [ seg] , ident. span , kind, initial_res, res) ;
824+ if has_reported_inner_attr_error
825+ && let Res :: Def ( DefKind :: Macro ( MacroKind :: Attr ) , _) = res
826+ && let None = initial_res
827+ {
828+ // Do not emit an indeterminate resolution and later errors when an outer
829+ // attribute wasn't found, as this can be knock down effects. #118455
830+ raise_fatal_error = true ;
831+ } else {
832+ let res = binding. res ( ) ;
833+ check_consistency ( self , & [ seg] , ident. span , kind, initial_res, res) ;
834+ } ;
814835 if res == Res :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelperCompat ) {
815836 let node_id = self
816837 . invocation_parents
@@ -825,7 +846,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
825846 ) ;
826847 }
827848 }
828- Err ( ..) => {
849+ Err ( _) => {
850+ if inner_attr {
851+ has_reported_inner_attr_error = true ;
852+ }
829853 let expected = kind. descr_expected ( ) ;
830854
831855 let mut err = self . tcx . sess . create_err ( CannotFindIdentInThisScope {
@@ -851,6 +875,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
851875 None ,
852876 ) ;
853877 }
878+
879+ if raise_fatal_error {
880+ // When we encounter an inner attribute failure, and subsequent successful macro
881+ // resolutions following early resolution failures. This is so when an outer attribute
882+ // isn't found, and we encounter `derive` attributes, we won't raise errors caused by
883+ // any code that relies on those derives having been evaluated. We don't attempt to
884+ // recover because the behavior of those derives could have been modified by the outer
885+ // attribute, causing *other* errors, so it is safest to just stop early instead.
886+ FatalError . raise ( ) ;
887+ }
854888 }
855889
856890 fn check_stability_and_deprecation (
0 commit comments