@@ -548,7 +548,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
548548        let  fcx_typeck_results = self . fcx . typeck_results . borrow ( ) ; 
549549        assert_eq ! ( fcx_typeck_results. hir_owner,  self . typeck_results. hir_owner) ; 
550550        for  ( predicate,  cause)  in  & fcx_typeck_results. coroutine_stalled_predicates  { 
551-             let  ( predicate,  cause)  = self . resolve ( ( * predicate,  cause. clone ( ) ) ,  & cause. span ) ; 
551+             let  ( predicate,  cause)  =
552+                 self . resolve_coroutine_predicate ( ( * predicate,  cause. clone ( ) ) ,  & cause. span ) ; 
552553            self . typeck_results . coroutine_stalled_predicates . insert ( ( predicate,  cause) ) ; 
553554        } 
554555    } 
@@ -730,7 +731,25 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
730731        T :  TypeFoldable < TyCtxt < ' tcx > > , 
731732    { 
732733        let  value = self . fcx . resolve_vars_if_possible ( value) ; 
733-         let  value = value. fold_with ( & mut  Resolver :: new ( self . fcx ,  span,  self . body ) ) ; 
734+         let  value = value. fold_with ( & mut  Resolver :: new ( self . fcx ,  span,  self . body ,  true ) ) ; 
735+         assert ! ( !value. has_infer( ) ) ; 
736+ 
737+         // We may have introduced e.g. `ty::Error`, if inference failed, make sure 
738+         // to mark the `TypeckResults` as tainted in that case, so that downstream 
739+         // users of the typeck results don't produce extra errors, or worse, ICEs. 
740+         if  let  Err ( guar)  = value. error_reported ( )  { 
741+             self . typeck_results . tainted_by_errors  = Some ( guar) ; 
742+         } 
743+ 
744+         value
745+     } 
746+ 
747+     fn  resolve_coroutine_predicate < T > ( & mut  self ,  value :  T ,  span :  & dyn  Locatable )  -> T 
748+     where 
749+         T :  TypeFoldable < TyCtxt < ' tcx > > , 
750+     { 
751+         let  value = self . fcx . resolve_vars_if_possible ( value) ; 
752+         let  value = value. fold_with ( & mut  Resolver :: new ( self . fcx ,  span,  self . body ,  false ) ) ; 
734753        assert ! ( !value. has_infer( ) ) ; 
735754
736755        // We may have introduced e.g. `ty::Error`, if inference failed, make sure 
@@ -774,8 +793,9 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
774793        fcx :  & ' cx  FnCtxt < ' cx ,  ' tcx > , 
775794        span :  & ' cx  dyn  Locatable , 
776795        body :  & ' tcx  hir:: Body < ' tcx > , 
796+         should_normalize :  bool , 
777797    )  -> Resolver < ' cx ,  ' tcx >  { 
778-         Resolver  {  fcx,  span,  body,  should_normalize :  fcx . next_trait_solver ( )  } 
798+         Resolver  {  fcx,  span,  body,  should_normalize } 
779799    } 
780800
781801    fn  report_error ( & self ,  p :  impl  Into < ty:: GenericArg < ' tcx > > )  -> ErrorGuaranteed  { 
@@ -805,10 +825,9 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
805825        T :  Into < ty:: GenericArg < ' tcx > >  + TypeSuperFoldable < TyCtxt < ' tcx > >  + Copy , 
806826    { 
807827        let  tcx = self . fcx . tcx ; 
808-         // We must deeply normalize in the new solver, since later lints 
809-         // expect that types that show up in the typeck are fully 
810-         // normalized. 
811-         let  mut  value = if  self . should_normalize  { 
828+         // We must deeply normalize in the new solver, since later lints expect 
829+         // that types that show up in the typeck are fully normalized. 
830+         let  mut  value = if  self . should_normalize  && self . fcx . next_trait_solver ( )  { 
812831            let  body_id = tcx. hir_body_owner_def_id ( self . body . id ( ) ) ; 
813832            let  cause = ObligationCause :: misc ( self . span . to_span ( tcx) ,  body_id) ; 
814833            let  at = self . fcx . at ( & cause,  self . fcx . param_env ) ; 
@@ -864,20 +883,15 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
864883    } 
865884
866885    fn  fold_const ( & mut  self ,  ct :  ty:: Const < ' tcx > )  -> ty:: Const < ' tcx >  { 
867-         self . handle_term ( ct,  ty:: Const :: outer_exclusive_binder,  |tcx,  guar| { 
868-             ty:: Const :: new_error ( tcx,  guar) 
869-         } ) 
870-         . super_fold_with ( self ) 
886+         self . handle_term ( ct,  ty:: Const :: outer_exclusive_binder,  ty:: Const :: new_error) 
871887    } 
872888
873889    fn  fold_predicate ( & mut  self ,  predicate :  ty:: Predicate < ' tcx > )  -> ty:: Predicate < ' tcx >  { 
874-         // Do not normalize predicates in the new solver. The new solver is 
875-         // supposed to handle unnormalized predicates and incorrectly normalizing 
876-         // them can be unsound, e.g. for `WellFormed` predicates. 
877-         let  prev = mem:: replace ( & mut  self . should_normalize ,  false ) ; 
878-         let  predicate = predicate. super_fold_with ( self ) ; 
879-         self . should_normalize  = prev; 
880-         predicate
890+         assert ! ( 
891+             !self . should_normalize, 
892+             "normalizing predicates in writeback is not generally sound" 
893+         ) ; 
894+         predicate. super_fold_with ( self ) 
881895    } 
882896} 
883897
0 commit comments