@@ -16,11 +16,15 @@ use rustc_index::IndexVec;
16
16
use rustc_infer:: infer:: canonical:: query_response:: make_query_region_constraints;
17
17
use rustc_infer:: infer:: canonical:: CanonicalVarValues ;
18
18
use rustc_infer:: infer:: canonical:: { CanonicalExt , QueryRegionConstraints } ;
19
+ use rustc_infer:: infer:: InferCtxt ;
19
20
use rustc_middle:: traits:: query:: NoSolution ;
20
21
use 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 ,
22
27
} ;
23
- use rustc_middle:: ty:: { self , BoundVar , GenericArgKind , Ty , TyCtxt , TypeFoldable } ;
24
28
use rustc_span:: DUMMY_SP ;
25
29
use std:: iter;
26
30
use std:: ops:: Deref ;
@@ -32,6 +36,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
32
36
& self ,
33
37
goal : Goal < ' tcx , T > ,
34
38
) -> ( 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
+
35
43
let mut orig_values = Default :: default ( ) ;
36
44
let canonical_goal = Canonicalizer :: canonicalize (
37
45
self . infcx ,
@@ -40,11 +48,9 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
40
48
QueryInput {
41
49
goal,
42
50
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 } ) ,
48
54
} ,
49
55
) ;
50
56
( orig_values, canonical_goal)
@@ -69,6 +75,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
69
75
previous call to `try_evaluate_added_goals!`"
70
76
) ;
71
77
78
+ let certainty = certainty. unify_with ( goals_certainty) ;
72
79
if let Certainty :: OVERFLOW = certainty {
73
80
// If we have overflow, it's probable that we're substituting a type
74
81
// into itself infinitely and any partial substitutions in the query
@@ -84,10 +91,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
84
91
return Ok ( self . make_ambiguous_response_no_constraints ( MaybeCause :: Overflow ) ) ;
85
92
}
86
93
87
- let certainty = certainty. unify_with ( goals_certainty) ;
88
94
let var_values = self . var_values ;
89
95
let external_constraints = self . compute_external_query_constraints ( ) ?;
90
96
97
+ let ( var_values, external_constraints) =
98
+ ( var_values, external_constraints) . fold_with ( & mut EagerResolver { infcx : self . infcx } ) ;
99
+
91
100
let canonical = Canonicalizer :: canonicalize (
92
101
self . infcx ,
93
102
CanonicalizeMode :: Response { max_input_universe : self . max_input_universe } ,
@@ -334,3 +343,65 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
334
343
Ok ( ( ) )
335
344
}
336
345
}
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