@@ -202,10 +202,25 @@ enum BuiltinImplConditions<'tcx> {
202
202
203
203
#[ derive( Copy , Clone ) ]
204
204
pub 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.
205
209
Recur ,
210
+ /// This is the behavior of the new trait solver, where inductive cycles
211
+ /// are treated as ambiguous and possibly holding.
206
212
Ambig ,
207
213
}
208
214
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
+
209
224
impl < ' cx , ' tcx > SelectionContext < ' cx , ' tcx > {
210
225
pub fn new ( infcx : & ' cx InferCtxt < ' tcx > ) -> SelectionContext < ' cx , ' tcx > {
211
226
SelectionContext {
@@ -223,6 +238,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
223
238
treat_inductive_cycle : TreatInductiveCycleAs ,
224
239
f : impl FnOnce ( & mut Self ) -> T ,
225
240
) -> 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( ) ) ;
226
244
let treat_inductive_cycle =
227
245
std:: mem:: replace ( & mut self . treat_inductive_cycle , treat_inductive_cycle) ;
228
246
let value = f ( self ) ;
@@ -741,10 +759,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
741
759
stack. update_reached_depth ( stack_arg. 1 ) ;
742
760
return Ok ( EvaluatedToOk ) ;
743
761
} 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 ( ) ) ;
748
763
}
749
764
}
750
765
return Ok ( EvaluatedToOk ) ;
@@ -862,10 +877,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
862
877
}
863
878
}
864
879
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 ( ) ) ,
869
881
ProjectAndUnifyResult :: MismatchedProjectionTypes ( _) => Ok ( EvaluatedToErr ) ,
870
882
}
871
883
}
@@ -1179,10 +1191,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1179
1191
Some ( EvaluatedToOk )
1180
1192
} else {
1181
1193
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 ( ) )
1186
1195
}
1187
1196
} else {
1188
1197
None
0 commit comments