8
8
/// section of the [rustc-dev-guide][c].
9
9
///
10
10
/// [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html
11
- pub use self :: canonicalize:: { CanonicalizeMode , Canonicalizer } ;
12
-
13
11
use super :: { CanonicalGoal , Certainty , EvalCtxt , Goal } ;
14
- use super :: { CanonicalResponse , QueryResult , Response } ;
12
+ use crate :: solve:: canonicalize:: { CanonicalizeMode , Canonicalizer } ;
13
+ use crate :: solve:: { CanonicalResponse , QueryResult , Response } ;
14
+ use rustc_infer:: infer:: canonical:: query_response:: make_query_region_constraints;
15
15
use rustc_infer:: infer:: canonical:: CanonicalVarValues ;
16
16
use rustc_infer:: infer:: canonical:: { CanonicalExt , QueryRegionConstraints } ;
17
- use rustc_infer :: traits:: query:: NoSolution ;
18
- use rustc_infer :: traits:: solve:: ExternalConstraintsData ;
17
+ use rustc_middle :: traits:: query:: NoSolution ;
18
+ use rustc_middle :: traits:: solve:: { ExternalConstraints , ExternalConstraintsData } ;
19
19
use rustc_middle:: ty:: { self , GenericArgKind } ;
20
+ use rustc_span:: DUMMY_SP ;
20
21
use std:: iter;
21
22
use std:: ops:: Deref ;
22
23
23
- mod canonicalize;
24
-
25
24
impl < ' tcx > EvalCtxt < ' _ , ' tcx > {
26
25
/// Canonicalizes the goal remembering the original values
27
26
/// for each bound variable.
@@ -30,7 +29,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
30
29
goal : Goal < ' tcx , ty:: Predicate < ' tcx > > ,
31
30
) -> ( Vec < ty:: GenericArg < ' tcx > > , CanonicalGoal < ' tcx > ) {
32
31
let mut orig_values = Default :: default ( ) ;
33
- let canonical_goal = self . canonicalize ( CanonicalizeMode :: Input , & mut orig_values, goal) ;
32
+ let canonical_goal = Canonicalizer :: canonicalize (
33
+ self . infcx ,
34
+ CanonicalizeMode :: Input ,
35
+ & mut orig_values,
36
+ goal,
37
+ ) ;
34
38
( orig_values, canonical_goal)
35
39
}
36
40
@@ -41,7 +45,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
41
45
/// - `external_constraints`: additional constraints which aren't expressable
42
46
/// using simple unification of inference variables.
43
47
#[ instrument( level = "debug" , skip( self ) ) ]
44
- pub ( super ) fn evaluate_added_goals_and_make_canonical_response (
48
+ pub ( in crate :: solve ) fn evaluate_added_goals_and_make_canonical_response (
45
49
& mut self ,
46
50
certainty : Certainty ,
47
51
) -> QueryResult < ' tcx > {
@@ -51,14 +55,35 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
51
55
let external_constraints = self . compute_external_query_constraints ( ) ?;
52
56
53
57
let response = Response { var_values : self . var_values , external_constraints, certainty } ;
54
- let canonical = self . canonicalize (
58
+ let canonical = Canonicalizer :: canonicalize (
59
+ self . infcx ,
55
60
CanonicalizeMode :: Response { max_input_universe : self . max_input_universe } ,
56
61
& mut Default :: default ( ) ,
57
62
response,
58
63
) ;
59
64
Ok ( canonical)
60
65
}
61
66
67
+ #[ instrument( level = "debug" , skip( self ) , ret) ]
68
+ fn compute_external_query_constraints ( & self ) -> Result < ExternalConstraints < ' tcx > , NoSolution > {
69
+ // Cannot use `take_registered_region_obligations` as we may compute the response
70
+ // inside of a `probe` whenever we have multiple choices inside of the solver.
71
+ let region_obligations = self . infcx . inner . borrow ( ) . region_obligations ( ) . to_owned ( ) ;
72
+ let region_constraints = self . infcx . with_region_constraints ( |region_constraints| {
73
+ make_query_region_constraints (
74
+ self . tcx ( ) ,
75
+ region_obligations
76
+ . iter ( )
77
+ . map ( |r_o| ( r_o. sup_type , r_o. sub_region , r_o. origin . to_constraint_category ( ) ) ) ,
78
+ region_constraints,
79
+ )
80
+ } ) ;
81
+ let opaque_types = self . infcx . clone_opaque_types_for_query_response ( ) ;
82
+ Ok ( self
83
+ . tcx ( )
84
+ . mk_external_constraints ( ExternalConstraintsData { region_constraints, opaque_types } ) )
85
+ }
86
+
62
87
/// After calling a canonical query, we apply the constraints returned
63
88
/// by the query using this function.
64
89
///
@@ -98,10 +123,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
98
123
// FIXME: Longterm canonical queries should deal with all placeholders
99
124
// created inside of the query directly instead of returning them to the
100
125
// caller.
101
- let prev_universe = self . universe ( ) ;
126
+ let prev_universe = self . infcx . universe ( ) ;
102
127
let universes_created_in_query = response. max_universe . index ( ) + 1 ;
103
128
for _ in 0 ..universes_created_in_query {
104
- self . create_next_universe ( ) ;
129
+ self . infcx . create_next_universe ( ) ;
105
130
}
106
131
107
132
let var_values = response. value . var_values ;
@@ -144,7 +169,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
144
169
// A variable from inside a binder of the query. While ideally these shouldn't
145
170
// exist at all (see the FIXME at the start of this method), we have to deal with
146
171
// them for now.
147
- self . instantiate_canonical_var ( info, |idx| {
172
+ self . infcx . instantiate_canonical_var ( DUMMY_SP , info, |idx| {
148
173
ty:: UniverseIndex :: from ( prev_universe. index ( ) + idx. index ( ) )
149
174
} )
150
175
} else if info. is_existential ( ) {
@@ -158,7 +183,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
158
183
if let Some ( v) = opt_values[ index] {
159
184
v
160
185
} else {
161
- self . instantiate_canonical_var ( info, |_| prev_universe)
186
+ self . infcx . instantiate_canonical_var ( DUMMY_SP , info, |_| prev_universe)
162
187
}
163
188
} else {
164
189
// For placeholders which were already part of the input, we simply map this
0 commit comments