@@ -202,10 +202,25 @@ enum BuiltinImplConditions<'tcx> {
202202
203203#[ derive( Copy , Clone ) ]
204204pub enum TreatInductiveCycleAs {
205+ /// This is the previous behavior, where `Recur` represents an inductive
206+ /// cycle that is known not to hold. This is not forwards-compatible with
207+ /// coinduction, and will be deprecated. This is the default behavior
208+ /// of the old trait solver due to back-compat reasons.
205209 Recur ,
210+ /// This is the behavior of the new trait solver, where inductive cycles
211+ /// are treated as ambiguous and possibly holding.
206212 Ambig ,
207213}
208214
215+ impl From < TreatInductiveCycleAs > for EvaluationResult {
216+ fn from ( treat : TreatInductiveCycleAs ) -> EvaluationResult {
217+ match treat {
218+ TreatInductiveCycleAs :: Ambig => EvaluatedToUnknown ,
219+ TreatInductiveCycleAs :: Recur => EvaluatedToRecur ,
220+ }
221+ }
222+ }
223+
209224impl < ' cx , ' tcx > SelectionContext < ' cx , ' tcx > {
210225 pub fn new ( infcx : & ' cx InferCtxt < ' tcx > ) -> SelectionContext < ' cx , ' tcx > {
211226 SelectionContext {
@@ -223,6 +238,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
223238 treat_inductive_cycle : TreatInductiveCycleAs ,
224239 f : impl FnOnce ( & mut Self ) -> T ,
225240 ) -> T {
241+ // Should be executed in a context where caching is disabled,
242+ // otherwise the cache is poisoned with the temporary result.
243+ assert ! ( self . is_intercrate( ) ) ;
226244 let treat_inductive_cycle =
227245 std:: mem:: replace ( & mut self . treat_inductive_cycle , treat_inductive_cycle) ;
228246 let value = f ( self ) ;
@@ -741,10 +759,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
741759 stack. update_reached_depth ( stack_arg. 1 ) ;
742760 return Ok ( EvaluatedToOk ) ;
743761 } else {
744- match self . treat_inductive_cycle {
745- TreatInductiveCycleAs :: Ambig => return Ok ( EvaluatedToUnknown ) ,
746- TreatInductiveCycleAs :: Recur => return Ok ( EvaluatedToRecur ) ,
747- }
762+ return Ok ( self . treat_inductive_cycle . into ( ) ) ;
748763 }
749764 }
750765 return Ok ( EvaluatedToOk ) ;
@@ -862,10 +877,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
862877 }
863878 }
864879 ProjectAndUnifyResult :: FailedNormalization => Ok ( EvaluatedToAmbig ) ,
865- ProjectAndUnifyResult :: Recursive => match self . treat_inductive_cycle {
866- TreatInductiveCycleAs :: Ambig => return Ok ( EvaluatedToUnknown ) ,
867- TreatInductiveCycleAs :: Recur => return Ok ( EvaluatedToRecur ) ,
868- } ,
880+ ProjectAndUnifyResult :: Recursive => Ok ( self . treat_inductive_cycle . into ( ) ) ,
869881 ProjectAndUnifyResult :: MismatchedProjectionTypes ( _) => Ok ( EvaluatedToErr ) ,
870882 }
871883 }
@@ -1179,10 +1191,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11791191 Some ( EvaluatedToOk )
11801192 } else {
11811193 debug ! ( "evaluate_stack --> recursive, inductive" ) ;
1182- match self . treat_inductive_cycle {
1183- TreatInductiveCycleAs :: Ambig => Some ( EvaluatedToUnknown ) ,
1184- TreatInductiveCycleAs :: Recur => Some ( EvaluatedToRecur ) ,
1185- }
1194+ Some ( self . treat_inductive_cycle . into ( ) )
11861195 }
11871196 } else {
11881197 None
0 commit comments