88/// section of the [rustc-dev-guide][c].
99///
1010/// [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html
11- pub use self :: canonicalize:: { CanonicalizeMode , Canonicalizer } ;
12-
1311use 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;
1515use rustc_infer:: infer:: canonical:: CanonicalVarValues ;
1616use 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 } ;
1919use rustc_middle:: ty:: { self , GenericArgKind } ;
20+ use rustc_span:: DUMMY_SP ;
2021use std:: iter;
2122use std:: ops:: Deref ;
2223
23- mod canonicalize;
24-
2524impl < ' tcx > EvalCtxt < ' _ , ' tcx > {
2625 /// Canonicalizes the goal remembering the original values
2726 /// for each bound variable.
@@ -30,7 +29,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
3029 goal : Goal < ' tcx , ty:: Predicate < ' tcx > > ,
3130 ) -> ( Vec < ty:: GenericArg < ' tcx > > , CanonicalGoal < ' tcx > ) {
3231 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+ ) ;
3438 ( orig_values, canonical_goal)
3539 }
3640
@@ -41,7 +45,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
4145 /// - `external_constraints`: additional constraints which aren't expressable
4246 /// using simple unification of inference variables.
4347 #[ 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 (
4549 & mut self ,
4650 certainty : Certainty ,
4751 ) -> QueryResult < ' tcx > {
@@ -51,14 +55,35 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
5155 let external_constraints = self . compute_external_query_constraints ( ) ?;
5256
5357 let response = Response { var_values : self . var_values , external_constraints, certainty } ;
54- let canonical = self . canonicalize (
58+ let canonical = Canonicalizer :: canonicalize (
59+ self . infcx ,
5560 CanonicalizeMode :: Response { max_input_universe : self . max_input_universe } ,
5661 & mut Default :: default ( ) ,
5762 response,
5863 ) ;
5964 Ok ( canonical)
6065 }
6166
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+
6287 /// After calling a canonical query, we apply the constraints returned
6388 /// by the query using this function.
6489 ///
@@ -98,10 +123,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
98123 // FIXME: Longterm canonical queries should deal with all placeholders
99124 // created inside of the query directly instead of returning them to the
100125 // caller.
101- let prev_universe = self . universe ( ) ;
126+ let prev_universe = self . infcx . universe ( ) ;
102127 let universes_created_in_query = response. max_universe . index ( ) + 1 ;
103128 for _ in 0 ..universes_created_in_query {
104- self . create_next_universe ( ) ;
129+ self . infcx . create_next_universe ( ) ;
105130 }
106131
107132 let var_values = response. value . var_values ;
@@ -144,7 +169,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
144169 // A variable from inside a binder of the query. While ideally these shouldn't
145170 // exist at all (see the FIXME at the start of this method), we have to deal with
146171 // them for now.
147- self . instantiate_canonical_var ( info, |idx| {
172+ self . infcx . instantiate_canonical_var ( DUMMY_SP , info, |idx| {
148173 ty:: UniverseIndex :: from ( prev_universe. index ( ) + idx. index ( ) )
149174 } )
150175 } else if info. is_existential ( ) {
@@ -158,7 +183,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
158183 if let Some ( v) = opt_values[ index] {
159184 v
160185 } else {
161- self . instantiate_canonical_var ( info, |_| prev_universe)
186+ self . infcx . instantiate_canonical_var ( DUMMY_SP , info, |_| prev_universe)
162187 }
163188 } else {
164189 // For placeholders which were already part of the input, we simply map this
0 commit comments