@@ -15,7 +15,7 @@ use rustc_ast_pretty::pprust;
15
15
use rustc_attr:: StabilityLevel ;
16
16
use rustc_data_structures:: intern:: Interned ;
17
17
use rustc_data_structures:: sync:: Lrc ;
18
- use rustc_errors:: { struct_span_err, Applicability } ;
18
+ use rustc_errors:: { struct_span_err, Applicability , FatalError } ;
19
19
use rustc_expand:: base:: { Annotatable , DeriveResolutions , Indeterminate , ResolverExpand } ;
20
20
use rustc_expand:: base:: { SyntaxExtension , SyntaxExtensionKind } ;
21
21
use rustc_expand:: compile_declarative_macro;
@@ -373,6 +373,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
373
373
match self . resolve_macro_path (
374
374
path,
375
375
Some ( MacroKind :: Derive ) ,
376
+ false ,
376
377
& parent_scope,
377
378
true ,
378
379
force,
@@ -504,8 +505,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
504
505
force : bool ,
505
506
soft_custom_inner_attributes_gate : bool ,
506
507
) -> 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
+ ) {
509
516
Ok ( ( Some ( ext) , res) ) => ( ext, res) ,
510
517
Ok ( ( None , res) ) => ( self . dummy_ext ( kind) , res) ,
511
518
Err ( Determinacy :: Determined ) => ( self . dummy_ext ( kind) , Res :: Err ) ,
@@ -627,6 +634,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
627
634
& mut self ,
628
635
path : & ast:: Path ,
629
636
kind : Option < MacroKind > ,
637
+ inner_attr : bool ,
630
638
parent_scope : & ParentScope < ' a > ,
631
639
trace : bool ,
632
640
force : bool ,
@@ -685,6 +693,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
685
693
self . single_segment_macro_resolutions . push ( (
686
694
path[ 0 ] . ident ,
687
695
kind,
696
+ inner_attr,
688
697
* parent_scope,
689
698
binding. ok ( ) ,
690
699
) ) ;
@@ -794,7 +803,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
794
803
}
795
804
796
805
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 {
798
809
match self . early_resolve_ident_in_lexical_scope (
799
810
ident,
800
811
ScopeSet :: Macro ( kind) ,
@@ -810,7 +821,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
810
821
} ) ;
811
822
let res = binding. res ( ) ;
812
823
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
+ } ;
814
835
if res == Res :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelperCompat ) {
815
836
let node_id = self
816
837
. invocation_parents
@@ -825,7 +846,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
825
846
) ;
826
847
}
827
848
}
828
- Err ( ..) => {
849
+ Err ( _) => {
850
+ if inner_attr {
851
+ has_reported_inner_attr_error = true ;
852
+ }
829
853
let expected = kind. descr_expected ( ) ;
830
854
831
855
let mut err = self . tcx . sess . create_err ( CannotFindIdentInThisScope {
@@ -851,6 +875,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
851
875
None ,
852
876
) ;
853
877
}
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
+ }
854
888
}
855
889
856
890
fn check_stability_and_deprecation (
0 commit comments