@@ -104,50 +104,20 @@ impl<'t, I: Interner> Unifier<'t, I> {
104104 (
105105 & TyData :: InferenceVar ( var1, kind1) ,
106106 & TyData :: InferenceVar ( var2, kind2) ,
107- ) if kind1 == kind2 => {
108- debug ! ( "unify_ty_ty: unify_var_var({:?}, {:?})" , var1, var2) ;
109- let var1 = EnaVariable :: from ( var1) ;
110- let var2 = EnaVariable :: from ( var2) ;
111- Ok ( self
112- . table
113- . unify
114- . unify_var_var ( var1, var2)
115- . expect ( "unification of two unbound variables cannot fail" ) )
116- }
117-
118- // General inference variables can be unified with more specific
119- // inference variables, but they need to inherit the specific
120- // variable's type kind. The general_var kind != the specific_var
121- // kind because of the prior match arm
122- (
123- & TyData :: InferenceVar ( general_var, TyKind :: General ) ,
124- specific_ty_data @ & TyData :: InferenceVar ( _, _)
125- )
126- | (
127- specific_ty_data @ & TyData :: InferenceVar ( _, _) ,
128- & TyData :: InferenceVar ( general_var, TyKind :: General )
129- ) => {
130- let specific_ty = specific_ty_data. clone ( ) . intern ( interner) ;
131- self . table
132- . unify
133- . unify_var_value ( general_var, InferenceValue :: from_ty ( interner, specific_ty. clone ( ) ) )
134- . unwrap ( ) ;
135-
136- debug ! ( "unify_ty_ty: general kinded var {:?} set to {:?}" , general_var, specific_ty) ;
137- Ok ( ( ) )
138- }
139-
140- // Tried to unify inference variables with mis-matching specific type kinds (not caught
141- // by prior match arms)
142- (
143- & TyData :: InferenceVar ( _, kind1) ,
144- & TyData :: InferenceVar ( _, kind2) ,
145107 ) => {
146- debug ! (
147- "Tried to unify mis-matching inference variables: {:?} and {:?}" ,
148- kind1, kind2
149- ) ;
150- Err ( NoSolution )
108+ if kind1 == kind2 {
109+ self . unify_var_var ( var1, var2)
110+ } else if kind1 == TyKind :: General {
111+ self . unify_general_var_specific_ty ( var1, b. clone ( ) )
112+ } else if kind2 == TyKind :: General {
113+ self . unify_general_var_specific_ty ( var2, a. clone ( ) )
114+ } else {
115+ debug ! (
116+ "Tried to unify mis-matching inference variables: {:?} and {:?}" ,
117+ kind1, kind2
118+ ) ;
119+ Err ( NoSolution )
120+ }
151121 }
152122
153123 // Unifying an inference variable with a non-inference variable.
@@ -230,6 +200,43 @@ impl<'t, I: Interner> Unifier<'t, I> {
230200 }
231201 }
232202
203+ /// Unify two inference variables
204+ fn unify_var_var ( & mut self , a : InferenceVar , b : InferenceVar ) -> Fallible < ( ) > {
205+ debug ! ( "unify_var_var({:?}, {:?})" , a, b) ;
206+ let var1 = EnaVariable :: from ( a) ;
207+ let var2 = EnaVariable :: from ( b) ;
208+ Ok ( self
209+ . table
210+ . unify
211+ . unify_var_var ( var1, var2)
212+ . expect ( "unification of two unbound variables cannot fail" ) )
213+ }
214+
215+ /// Unify a general inference variable with a specific inference variable
216+ /// (type kind is not `General`). For example, unify a `TyKind::General`
217+ /// inference variable with a `TyKind::Integer` variable, resulting in the
218+ /// general inference variable narrowing to an integer variable.
219+ fn unify_general_var_specific_ty (
220+ & mut self ,
221+ general_var : InferenceVar ,
222+ specific_ty : Ty < I > ,
223+ ) -> Fallible < ( ) > {
224+ debug ! (
225+ "unify_general_var_specific_var({:?}, {:?})" ,
226+ general_var, specific_ty
227+ ) ;
228+
229+ self . table
230+ . unify
231+ . unify_var_value (
232+ general_var,
233+ InferenceValue :: from_ty ( self . interner , specific_ty) ,
234+ )
235+ . unwrap ( ) ;
236+
237+ Ok ( ( ) )
238+ }
239+
233240 fn unify_binders < ' a , T , R > (
234241 & mut self ,
235242 a : impl IntoBindersAndValue < ' a , I , Value = T > + Copy + Debug ,
0 commit comments