Skip to content

Commit 48f62e4

Browse files
committed
Refactor inference var unification from matches into separate methods
1 parent 2224d2a commit 48f62e4

File tree

1 file changed

+50
-43
lines changed

1 file changed

+50
-43
lines changed

chalk-solve/src/infer/unify.rs

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)