@@ -9,6 +9,7 @@ use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
9
9
use rustc_type_ir:: inherent:: * ;
10
10
use rustc_type_ir:: relate:: Relate ;
11
11
use rustc_type_ir:: relate:: solver_relating:: RelateExt ;
12
+ use rustc_type_ir:: search_graph:: PathKind ;
12
13
use rustc_type_ir:: visit:: { TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor } ;
13
14
use rustc_type_ir:: { self as ty, CanonicalVarValues , InferCtxtLike , Interner , TypingMode } ;
14
15
use rustc_type_ir_macros:: { Lift_Generic , TypeFoldable_Generic , TypeVisitable_Generic } ;
@@ -20,12 +21,51 @@ use crate::solve::inspect::{self, ProofTreeBuilder};
20
21
use crate :: solve:: search_graph:: SearchGraph ;
21
22
use crate :: solve:: {
22
23
CanonicalInput , Certainty , FIXPOINT_STEP_LIMIT , Goal , GoalEvaluationKind , GoalSource ,
23
- HasChanged , NestedNormalizationGoals , NoSolution , PredefinedOpaquesData , QueryResult ,
24
+ HasChanged , NestedNormalizationGoals , NoSolution , PredefinedOpaquesData , QueryInput ,
25
+ QueryResult ,
24
26
} ;
25
27
26
28
pub ( super ) mod canonical;
27
29
mod probe;
28
30
31
+ /// The kind of goal we're currently proving.
32
+ ///
33
+ /// This has effects on cycle handling handling and on how we compute
34
+ /// query responses, see the variant descriptions for more info.
35
+ #[ derive( Debug , Copy , Clone ) ]
36
+ enum CurrentGoalKind {
37
+ Misc ,
38
+ /// We're proving an trait goal for a coinductive trait, either an auto trait or `Sized`.
39
+ ///
40
+ /// These are currently the only goals whose impl where-clauses are considered to be
41
+ /// productive steps.
42
+ CoinductiveTrait ,
43
+ /// Unlike other goals, `NormalizesTo` goals act like functions with the expected term
44
+ /// always being fully unconstrained. This would weaken inference however, as the nested
45
+ /// goals never get the inference constraints from the actual normalized-to type.
46
+ ///
47
+ /// Because of this we return any ambiguous nested goals from `NormalizesTo` to the
48
+ /// caller when then adds these to its own context. The caller is always an `AliasRelate`
49
+ /// goal so this never leaks out of the solver.
50
+ NormalizesTo ,
51
+ }
52
+
53
+ impl CurrentGoalKind {
54
+ fn from_query_input < I : Interner > ( cx : I , input : QueryInput < I , I :: Predicate > ) -> CurrentGoalKind {
55
+ match input. goal . predicate . kind ( ) . skip_binder ( ) {
56
+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => {
57
+ if cx. trait_is_coinductive ( pred. trait_ref . def_id ) {
58
+ CurrentGoalKind :: CoinductiveTrait
59
+ } else {
60
+ CurrentGoalKind :: Misc
61
+ }
62
+ }
63
+ ty:: PredicateKind :: NormalizesTo ( _) => CurrentGoalKind :: NormalizesTo ,
64
+ _ => CurrentGoalKind :: Misc ,
65
+ }
66
+ }
67
+ }
68
+
29
69
pub struct EvalCtxt < ' a , D , I = <D as SolverDelegate >:: Interner >
30
70
where
31
71
D : SolverDelegate < Interner = I > ,
@@ -51,14 +91,10 @@ where
51
91
/// The variable info for the `var_values`, only used to make an ambiguous response
52
92
/// with no constraints.
53
93
variables : I :: CanonicalVars ,
54
- /// Whether we're currently computing a `NormalizesTo` goal. Unlike other goals,
55
- /// `NormalizesTo` goals act like functions with the expected term always being
56
- /// fully unconstrained. This would weaken inference however, as the nested goals
57
- /// never get the inference constraints from the actual normalized-to type. Because
58
- /// of this we return any ambiguous nested goals from `NormalizesTo` to the caller
59
- /// when then adds these to its own context. The caller is always an `AliasRelate`
60
- /// goal so this never leaks out of the solver.
61
- is_normalizes_to_goal : bool ,
94
+
95
+ /// What kind of goal we're currently computing, see the enum definition
96
+ /// for more info.
97
+ current_goal_kind : CurrentGoalKind ,
62
98
pub ( super ) var_values : CanonicalVarValues < I > ,
63
99
64
100
predefined_opaques_in_body : I :: PredefinedOpaques ,
@@ -226,8 +262,11 @@ where
226
262
self . delegate . typing_mode ( )
227
263
}
228
264
229
- pub ( super ) fn set_is_normalizes_to_goal ( & mut self ) {
230
- self . is_normalizes_to_goal = true ;
265
+ pub ( super ) fn step_kind_for_source ( & self , source : GoalSource ) -> PathKind {
266
+ match ( self . current_goal_kind , source) {
267
+ ( CurrentGoalKind :: CoinductiveTrait , GoalSource :: ImplWhereBound ) => PathKind :: Coinductive ,
268
+ _ => PathKind :: Inductive ,
269
+ }
231
270
}
232
271
233
272
/// Creates a root evaluation context and search graph. This should only be
@@ -256,7 +295,7 @@ where
256
295
max_input_universe : ty:: UniverseIndex :: ROOT ,
257
296
variables : Default :: default ( ) ,
258
297
var_values : CanonicalVarValues :: dummy ( ) ,
259
- is_normalizes_to_goal : false ,
298
+ current_goal_kind : CurrentGoalKind :: Misc ,
260
299
origin_span,
261
300
tainted : Ok ( ( ) ) ,
262
301
} ;
@@ -294,7 +333,7 @@ where
294
333
delegate,
295
334
variables : canonical_input. canonical . variables ,
296
335
var_values,
297
- is_normalizes_to_goal : false ,
336
+ current_goal_kind : CurrentGoalKind :: from_query_input ( cx , input ) ,
298
337
predefined_opaques_in_body : input. predefined_opaques_in_body ,
299
338
max_input_universe : canonical_input. canonical . max_universe ,
300
339
search_graph,
@@ -340,6 +379,7 @@ where
340
379
cx : I ,
341
380
search_graph : & ' a mut SearchGraph < D > ,
342
381
canonical_input : CanonicalInput < I > ,
382
+ step_kind_from_parent : PathKind ,
343
383
goal_evaluation : & mut ProofTreeBuilder < D > ,
344
384
) -> QueryResult < I > {
345
385
let mut canonical_goal_evaluation =
@@ -352,6 +392,7 @@ where
352
392
search_graph. with_new_goal (
353
393
cx,
354
394
canonical_input,
395
+ step_kind_from_parent,
355
396
& mut canonical_goal_evaluation,
356
397
|search_graph, canonical_goal_evaluation| {
357
398
EvalCtxt :: enter_canonical (
@@ -395,12 +436,10 @@ where
395
436
/// `NormalizesTo` is only used by `AliasRelate`, all other callsites
396
437
/// should use [`EvalCtxt::evaluate_goal`] which discards that empty
397
438
/// storage.
398
- // FIXME(-Znext-solver=coinduction): `_source` is currently unused but will
399
- // be necessary once we implement the new coinduction approach.
400
439
pub ( super ) fn evaluate_goal_raw (
401
440
& mut self ,
402
441
goal_evaluation_kind : GoalEvaluationKind ,
403
- _source : GoalSource ,
442
+ source : GoalSource ,
404
443
goal : Goal < I , I :: Predicate > ,
405
444
) -> Result < ( NestedNormalizationGoals < I > , HasChanged , Certainty ) , NoSolution > {
406
445
let ( orig_values, canonical_goal) = self . canonicalize_goal ( goal) ;
@@ -410,6 +449,7 @@ where
410
449
self . cx ( ) ,
411
450
self . search_graph ,
412
451
canonical_goal,
452
+ self . step_kind_for_source ( source) ,
413
453
& mut goal_evaluation,
414
454
) ;
415
455
let response = match canonical_response {
0 commit comments