@@ -28,11 +28,13 @@ use super::{InferCtxt, MiscVariable, TypeTrace};
28
28
use super :: lub:: Lub ;
29
29
use super :: sub:: Sub ;
30
30
use super :: type_variable:: TypeVariableValue ;
31
+ use super :: const_variable:: ConstVariableValue ;
31
32
32
33
use crate :: hir:: def_id:: DefId ;
34
+ use crate :: mir:: interpret:: ConstValue ;
33
35
use crate :: ty:: { IntType , UintType } ;
34
- use crate :: ty:: { self , Ty , TyCtxt } ;
35
- use crate :: ty:: error:: TypeError ;
36
+ use crate :: ty:: { self , Ty , TyCtxt , InferConst , LazyConst } ;
37
+ use crate :: ty:: error:: { ConstError , TypeError } ;
36
38
use crate :: ty:: relate:: { self , Relate , RelateResult , TypeRelation } ;
37
39
use crate :: ty:: subst:: SubstsRef ;
38
40
use crate :: traits:: { Obligation , PredicateObligations } ;
@@ -107,13 +109,68 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
107
109
Err ( TypeError :: Sorts ( ty:: relate:: expected_found ( relation, & a, & b) ) )
108
110
}
109
111
110
-
111
112
_ => {
112
113
ty:: relate:: super_relate_tys ( relation, a, b)
113
114
}
114
115
}
115
116
}
116
117
118
+ pub fn super_combine_consts < R > (
119
+ & self ,
120
+ relation : & mut R ,
121
+ a : & ' tcx LazyConst < ' tcx > ,
122
+ b : & ' tcx LazyConst < ' tcx > ,
123
+ ) -> RelateResult < ' tcx , & ' tcx LazyConst < ' tcx > >
124
+ where
125
+ R : TypeRelation < ' infcx , ' gcx , ' tcx > ,
126
+ {
127
+ let a_is_expected = relation. a_is_expected ( ) ;
128
+
129
+ if let ( & ty:: LazyConst :: Evaluated ( a_eval) , & ty:: LazyConst :: Evaluated ( b_eval) ) = ( a, b) {
130
+ match ( a_eval. val , b_eval. val ) {
131
+ ( ConstValue :: Infer ( InferConst :: Var ( a_vid) ) ,
132
+ ConstValue :: Infer ( InferConst :: Var ( b_vid) ) ) => {
133
+ self . const_unification_table
134
+ . borrow_mut ( )
135
+ . unify_var_var ( a_vid, b_vid)
136
+ . map_err ( |e| const_unification_error ( a_is_expected, e) ) ?;
137
+ return Ok ( a) ;
138
+ }
139
+
140
+ // All other cases of inference with other variables are errors.
141
+ ( ConstValue :: Infer ( InferConst :: Var ( _) ) , ConstValue :: Infer ( _) ) |
142
+ ( ConstValue :: Infer ( _) , ConstValue :: Infer ( InferConst :: Var ( _) ) ) => {
143
+ bug ! ( "tried to combine ConstValue::Infer/ConstValue::Infer(InferConst::Var)" )
144
+ }
145
+
146
+ ( ConstValue :: Infer ( InferConst :: Var ( vid) ) , _) => {
147
+ return self . unify_const_variable ( a_is_expected, vid, b) ;
148
+ }
149
+
150
+ ( _, ConstValue :: Infer ( InferConst :: Var ( vid) ) ) => {
151
+ return self . unify_const_variable ( !a_is_expected, vid, a) ;
152
+ }
153
+
154
+ _ => { }
155
+ }
156
+ }
157
+
158
+ ty:: relate:: super_relate_consts ( relation, a, b)
159
+ }
160
+
161
+ pub fn unify_const_variable (
162
+ & self ,
163
+ vid_is_expected : bool ,
164
+ vid : ty:: ConstVid < ' tcx > ,
165
+ value : & ' tcx LazyConst < ' tcx > ,
166
+ ) -> RelateResult < ' tcx , & ' tcx LazyConst < ' tcx > > {
167
+ self . const_unification_table
168
+ . borrow_mut ( )
169
+ . unify_var_value ( vid, ConstVariableValue :: Known { value } )
170
+ . map_err ( |e| const_unification_error ( vid_is_expected, e) ) ?;
171
+ Ok ( value)
172
+ }
173
+
117
174
fn unify_integral_variable ( & self ,
118
175
vid_is_expected : bool ,
119
176
vid : ty:: IntVid ,
0 commit comments