@@ -16,11 +16,15 @@ use rustc_index::IndexVec;
1616use rustc_infer:: infer:: canonical:: query_response:: make_query_region_constraints;
1717use rustc_infer:: infer:: canonical:: CanonicalVarValues ;
1818use rustc_infer:: infer:: canonical:: { CanonicalExt , QueryRegionConstraints } ;
19+ use rustc_infer:: infer:: InferCtxt ;
1920use rustc_middle:: traits:: query:: NoSolution ;
2021use rustc_middle:: traits:: solve:: {
21- ExternalConstraintsData , MaybeCause , PredefinedOpaquesData , QueryInput ,
22+ ExternalConstraintsData , MaybeCause , PredefinedOpaquesData , QueryInput ,
23+ } ;
24+ use rustc_middle:: ty:: {
25+ self , BoundVar , GenericArgKind , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable ,
26+ TypeVisitableExt ,
2227} ;
23- use rustc_middle:: ty:: { self , BoundVar , GenericArgKind , Ty , TyCtxt , TypeFoldable } ;
2428use rustc_span:: DUMMY_SP ;
2529use std:: iter;
2630use std:: ops:: Deref ;
@@ -32,6 +36,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
3236 & self ,
3337 goal : Goal < ' tcx , T > ,
3438 ) -> ( Vec < ty:: GenericArg < ' tcx > > , CanonicalInput < ' tcx , T > ) {
39+ let opaque_types = self . infcx . clone_opaque_types_for_query_response ( ) ;
40+ let ( goal, opaque_types) =
41+ ( goal, opaque_types) . fold_with ( & mut EagerResolver { infcx : self . infcx } ) ;
42+
3543 let mut orig_values = Default :: default ( ) ;
3644 let canonical_goal = Canonicalizer :: canonicalize (
3745 self . infcx ,
@@ -40,11 +48,9 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
4048 QueryInput {
4149 goal,
4250 anchor : self . infcx . defining_use_anchor ,
43- predefined_opaques_in_body : self . tcx ( ) . mk_predefined_opaques_in_body (
44- PredefinedOpaquesData {
45- opaque_types : self . infcx . clone_opaque_types_for_query_response ( ) ,
46- } ,
47- ) ,
51+ predefined_opaques_in_body : self
52+ . tcx ( )
53+ . mk_predefined_opaques_in_body ( PredefinedOpaquesData { opaque_types } ) ,
4854 } ,
4955 ) ;
5056 ( orig_values, canonical_goal)
@@ -69,6 +75,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
6975 previous call to `try_evaluate_added_goals!`"
7076 ) ;
7177
78+ let certainty = certainty. unify_with ( goals_certainty) ;
7279 if let Certainty :: OVERFLOW = certainty {
7380 // If we have overflow, it's probable that we're substituting a type
7481 // into itself infinitely and any partial substitutions in the query
@@ -84,10 +91,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
8491 return Ok ( self . make_ambiguous_response_no_constraints ( MaybeCause :: Overflow ) ) ;
8592 }
8693
87- let certainty = certainty. unify_with ( goals_certainty) ;
8894 let var_values = self . var_values ;
8995 let external_constraints = self . compute_external_query_constraints ( ) ?;
9096
97+ let ( var_values, external_constraints) =
98+ ( var_values, external_constraints) . fold_with ( & mut EagerResolver { infcx : self . infcx } ) ;
99+
91100 let canonical = Canonicalizer :: canonicalize (
92101 self . infcx ,
93102 CanonicalizeMode :: Response { max_input_universe : self . max_input_universe } ,
@@ -334,3 +343,65 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
334343 Ok ( ( ) )
335344 }
336345}
346+
347+ /// Resolves ty, region, and const vars to their inferred values or their root vars.
348+ struct EagerResolver < ' a , ' tcx > {
349+ infcx : & ' a InferCtxt < ' tcx > ,
350+ }
351+
352+ impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for EagerResolver < ' _ , ' tcx > {
353+ fn interner ( & self ) -> TyCtxt < ' tcx > {
354+ self . infcx . tcx
355+ }
356+
357+ fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
358+ match * t. kind ( ) {
359+ ty:: Infer ( ty:: TyVar ( vid) ) => match self . infcx . probe_ty_var ( vid) {
360+ Ok ( t) => t. fold_with ( self ) ,
361+ Err ( _) => Ty :: new_var ( self . infcx . tcx , self . infcx . root_var ( vid) ) ,
362+ } ,
363+ ty:: Infer ( ty:: IntVar ( vid) ) => self . infcx . opportunistic_resolve_int_var ( vid) ,
364+ ty:: Infer ( ty:: FloatVar ( vid) ) => self . infcx . opportunistic_resolve_float_var ( vid) ,
365+ _ => {
366+ if t. has_infer ( ) {
367+ t. super_fold_with ( self )
368+ } else {
369+ t
370+ }
371+ }
372+ }
373+ }
374+
375+ fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
376+ match * r {
377+ ty:: ReVar ( vid) => self
378+ . infcx
379+ . inner
380+ . borrow_mut ( )
381+ . unwrap_region_constraints ( )
382+ . opportunistic_resolve_var ( self . infcx . tcx , vid) ,
383+ _ => r,
384+ }
385+ }
386+
387+ fn fold_const ( & mut self , c : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
388+ match c. kind ( ) {
389+ ty:: ConstKind :: Infer ( ty:: InferConst :: Var ( vid) ) => {
390+ // FIXME: we need to fold the ty too, I think.
391+ match self . infcx . probe_const_var ( vid) {
392+ Ok ( c) => c. fold_with ( self ) ,
393+ Err ( _) => {
394+ ty:: Const :: new_var ( self . infcx . tcx , self . infcx . root_const_var ( vid) , c. ty ( ) )
395+ }
396+ }
397+ }
398+ _ => {
399+ if c. has_infer ( ) {
400+ c. super_fold_with ( self )
401+ } else {
402+ c
403+ }
404+ }
405+ }
406+ }
407+ }
0 commit comments