@@ -75,7 +75,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
75
75
wbcx. tables . upvar_list =
76
76
mem:: replace ( & mut self . tables . borrow_mut ( ) . upvar_list , Default :: default ( ) ) ;
77
77
78
- wbcx. tables . tainted_by_errors = self . is_tainted_by_errors ( ) ;
78
+ wbcx. tables . tainted_by_errors | = self . is_tainted_by_errors ( ) ;
79
79
80
80
debug ! ( "writeback: tables for {:?} are {:#?}" , item_def_id, wbcx. tables) ;
81
81
@@ -578,14 +578,21 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
578
578
}
579
579
}
580
580
581
- fn resolve < T > ( & self , x : & T , span : & dyn Locatable ) -> T
581
+ fn resolve < T > ( & mut self , x : & T , span : & dyn Locatable ) -> T
582
582
where
583
583
T : TypeFoldable < ' tcx > ,
584
584
{
585
- let x = x. fold_with ( & mut Resolver :: new ( self . fcx , span, self . body ) ) ;
585
+ let mut resolver = Resolver :: new ( self . fcx , span, self . body ) ;
586
+ let x = x. fold_with ( & mut resolver) ;
586
587
if cfg ! ( debug_assertions) && x. needs_infer ( ) {
587
588
span_bug ! ( span. to_span( self . fcx. tcx) , "writeback: `{:?}` has inference variables" , x) ;
588
589
}
590
+
591
+ // We may have introduced e.g. `ty::Error`, if inference failed, make sure
592
+ // to mark the `TypeckTables` as tainted in that case, so that downstream
593
+ // users of the tables don't produce extra errors, or worse, ICEs.
594
+ self . tables . tainted_by_errors |= resolver. replaced_with_error ;
595
+
589
596
x
590
597
}
591
598
}
@@ -613,6 +620,9 @@ struct Resolver<'cx, 'tcx> {
613
620
infcx : & ' cx InferCtxt < ' cx , ' tcx > ,
614
621
span : & ' cx dyn Locatable ,
615
622
body : & ' tcx hir:: Body < ' tcx > ,
623
+
624
+ /// Set to `true` if any `Ty` or `ty::Const` had to be replaced with an `Error`.
625
+ replaced_with_error : bool ,
616
626
}
617
627
618
628
impl < ' cx , ' tcx > Resolver < ' cx , ' tcx > {
@@ -621,7 +631,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
621
631
span : & ' cx dyn Locatable ,
622
632
body : & ' tcx hir:: Body < ' tcx > ,
623
633
) -> Resolver < ' cx , ' tcx > {
624
- Resolver { tcx : fcx. tcx , infcx : fcx, span, body }
634
+ Resolver { tcx : fcx. tcx , infcx : fcx, span, body, replaced_with_error : false }
625
635
}
626
636
627
637
fn report_error ( & self , t : Ty < ' tcx > ) {
@@ -644,6 +654,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
644
654
Err ( _) => {
645
655
debug ! ( "Resolver::fold_ty: input type `{:?}` not fully resolvable" , t) ;
646
656
self . report_error ( t) ;
657
+ self . replaced_with_error = true ;
647
658
self . tcx ( ) . types . err
648
659
}
649
660
}
@@ -661,6 +672,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
661
672
debug ! ( "Resolver::fold_const: input const `{:?}` not fully resolvable" , ct) ;
662
673
// FIXME: we'd like to use `self.report_error`, but it doesn't yet
663
674
// accept a &'tcx ty::Const.
675
+ self . replaced_with_error = true ;
664
676
self . tcx ( ) . consts . err
665
677
}
666
678
}
0 commit comments