@@ -118,6 +118,8 @@ pub struct SelectionContext<'cx, 'tcx> {
118
118
/// policy. In essence, canonicalized queries need their errors propagated
119
119
/// rather than immediately reported because we do not have accurate spans.
120
120
query_mode : TraitQueryMode ,
121
+
122
+ treat_inductive_cycle : TreatInductiveCycleAs ,
121
123
}
122
124
123
125
// A stack that walks back up the stack frame.
@@ -198,13 +200,32 @@ enum BuiltinImplConditions<'tcx> {
198
200
Ambiguous ,
199
201
}
200
202
203
+ enum TreatInductiveCycleAs {
204
+ Recur ,
205
+ Ambig ,
206
+ }
207
+
201
208
impl < ' cx , ' tcx > SelectionContext < ' cx , ' tcx > {
202
209
pub fn new ( infcx : & ' cx InferCtxt < ' tcx > ) -> SelectionContext < ' cx , ' tcx > {
203
210
SelectionContext {
204
211
infcx,
205
212
freshener : infcx. freshener ( ) ,
206
213
intercrate_ambiguity_causes : None ,
207
214
query_mode : TraitQueryMode :: Standard ,
215
+ treat_inductive_cycle : TreatInductiveCycleAs :: Recur ,
216
+ }
217
+ }
218
+
219
+ pub fn with_treat_inductive_cycle_as_ambiguous (
220
+ infcx : & ' cx InferCtxt < ' tcx > ,
221
+ ) -> SelectionContext < ' cx , ' tcx > {
222
+ assert ! ( infcx. intercrate, "this doesn't do caching yet, so don't use it out of intercrate" ) ;
223
+ SelectionContext {
224
+ infcx,
225
+ freshener : infcx. freshener ( ) ,
226
+ intercrate_ambiguity_causes : None ,
227
+ query_mode : TraitQueryMode :: Standard ,
228
+ treat_inductive_cycle : TreatInductiveCycleAs :: Ambig ,
208
229
}
209
230
}
210
231
@@ -719,7 +740,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
719
740
stack. update_reached_depth ( stack_arg. 1 ) ;
720
741
return Ok ( EvaluatedToOk ) ;
721
742
} else {
722
- return Ok ( EvaluatedToRecur ) ;
743
+ match self . treat_inductive_cycle {
744
+ TreatInductiveCycleAs :: Ambig => return Ok ( EvaluatedToAmbig ) ,
745
+ TreatInductiveCycleAs :: Recur => return Ok ( EvaluatedToRecur ) ,
746
+ }
723
747
}
724
748
}
725
749
return Ok ( EvaluatedToOk ) ;
@@ -837,7 +861,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
837
861
}
838
862
}
839
863
ProjectAndUnifyResult :: FailedNormalization => Ok ( EvaluatedToAmbig ) ,
840
- ProjectAndUnifyResult :: Recursive => Ok ( EvaluatedToRecur ) ,
864
+ ProjectAndUnifyResult :: Recursive => match self . treat_inductive_cycle {
865
+ TreatInductiveCycleAs :: Ambig => return Ok ( EvaluatedToAmbig ) ,
866
+ TreatInductiveCycleAs :: Recur => return Ok ( EvaluatedToRecur ) ,
867
+ } ,
841
868
ProjectAndUnifyResult :: MismatchedProjectionTypes ( _) => Ok ( EvaluatedToErr ) ,
842
869
}
843
870
}
@@ -1151,7 +1178,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1151
1178
Some ( EvaluatedToOk )
1152
1179
} else {
1153
1180
debug ! ( "evaluate_stack --> recursive, inductive" ) ;
1154
- Some ( EvaluatedToRecur )
1181
+ match self . treat_inductive_cycle {
1182
+ TreatInductiveCycleAs :: Ambig => Some ( EvaluatedToAmbig ) ,
1183
+ TreatInductiveCycleAs :: Recur => Some ( EvaluatedToRecur ) ,
1184
+ }
1155
1185
}
1156
1186
} else {
1157
1187
None
0 commit comments