@@ -75,7 +75,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7575 wbcx. tables . upvar_list =
7676 mem:: replace ( & mut self . tables . borrow_mut ( ) . upvar_list , Default :: default ( ) ) ;
7777
78- wbcx. tables . tainted_by_errors = self . is_tainted_by_errors ( ) ;
78+ wbcx. tables . tainted_by_errors | = self . is_tainted_by_errors ( ) ;
7979
8080 debug ! ( "writeback: tables for {:?} are {:#?}" , item_def_id, wbcx. tables) ;
8181
@@ -578,14 +578,21 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
578578 }
579579 }
580580
581- fn resolve < T > ( & self , x : & T , span : & dyn Locatable ) -> T
581+ fn resolve < T > ( & mut self , x : & T , span : & dyn Locatable ) -> T
582582 where
583583 T : TypeFoldable < ' tcx > ,
584584 {
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) ;
586587 if cfg ! ( debug_assertions) && x. needs_infer ( ) {
587588 span_bug ! ( span. to_span( self . fcx. tcx) , "writeback: `{:?}` has inference variables" , x) ;
588589 }
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+
589596 x
590597 }
591598}
@@ -613,6 +620,9 @@ struct Resolver<'cx, 'tcx> {
613620 infcx : & ' cx InferCtxt < ' cx , ' tcx > ,
614621 span : & ' cx dyn Locatable ,
615622 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 ,
616626}
617627
618628impl < ' cx , ' tcx > Resolver < ' cx , ' tcx > {
@@ -621,7 +631,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
621631 span : & ' cx dyn Locatable ,
622632 body : & ' tcx hir:: Body < ' tcx > ,
623633 ) -> 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 }
625635 }
626636
627637 fn report_error ( & self , t : Ty < ' tcx > ) {
@@ -644,6 +654,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
644654 Err ( _) => {
645655 debug ! ( "Resolver::fold_ty: input type `{:?}` not fully resolvable" , t) ;
646656 self . report_error ( t) ;
657+ self . replaced_with_error = true ;
647658 self . tcx ( ) . types . err
648659 }
649660 }
@@ -661,6 +672,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
661672 debug ! ( "Resolver::fold_const: input const `{:?}` not fully resolvable" , ct) ;
662673 // FIXME: we'd like to use `self.report_error`, but it doesn't yet
663674 // accept a &'tcx ty::Const.
675+ self . replaced_with_error = true ;
664676 self . tcx ( ) . consts . err
665677 }
666678 }
0 commit comments