Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir_ty/src/infer/unify.rs')
-rw-r--r--crates/hir_ty/src/infer/unify.rs47
1 files changed, 30 insertions, 17 deletions
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 8a6c34b493..deb536e511 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -1,6 +1,6 @@
//! Unification and canonicalization logic.
-use std::{fmt, iter, mem, sync::Arc};
+use std::{fmt, mem, sync::Arc};
use chalk_ir::{
cast::Cast, fold::Fold, interner::HasInterner, zip::Zip, FloatTy, IntTy, NoSolution,
@@ -9,13 +9,14 @@ use chalk_ir::{
use chalk_solve::infer::ParameterEnaVariableExt;
use ena::unify::UnifyKey;
use hir_expand::name;
+use stdx::never;
use super::{InferOk, InferResult, InferenceContext, TypeError};
use crate::{
db::HirDatabase, fold_tys, static_lifetime, traits::FnTrait, AliasEq, AliasTy, BoundVar,
- Canonical, Const, DebruijnIndex, GenericArg, Goal, Guidance, InEnvironment, InferenceVar,
- Interner, Lifetime, ProjectionTy, ProjectionTyExt, Scalar, Solution, Substitution,
- TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, VariableKind,
+ Canonical, Const, DebruijnIndex, GenericArg, GenericArgData, Goal, Guidance, InEnvironment,
+ InferenceVar, Interner, Lifetime, ParamKind, ProjectionTy, ProjectionTyExt, Scalar, Solution,
+ Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, VariableKind,
};
impl<'a> InferenceContext<'a> {
@@ -48,13 +49,13 @@ impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
// the solution may contain new variables, which we need to convert to new inference vars
let new_vars = Substitution::from_iter(
Interner,
- solution.binders.iter(Interner).map(|k| match k.kind {
+ solution.binders.iter(Interner).map(|k| match &k.kind {
VariableKind::Ty(TyVariableKind::General) => ctx.new_type_var().cast(Interner),
VariableKind::Ty(TyVariableKind::Integer) => ctx.new_integer_var().cast(Interner),
VariableKind::Ty(TyVariableKind::Float) => ctx.new_float_var().cast(Interner),
// Chalk can sometimes return new lifetime variables. We just use the static lifetime everywhere
VariableKind::Lifetime => static_lifetime().cast(Interner),
- _ => panic!("const variable in solution"),
+ VariableKind::Const(ty) => ctx.new_const_var(ty.clone()).cast(Interner),
}),
);
for (i, v) in solution.value.iter(Interner).enumerate() {
@@ -87,11 +88,17 @@ pub(crate) fn unify(
let mut table = InferenceTable::new(db, env);
let vars = Substitution::from_iter(
Interner,
- tys.binders
- .iter(Interner)
- // we always use type vars here because we want everything to
- // fallback to Unknown in the end (kind of hacky, as below)
- .map(|_| table.new_type_var()),
+ tys.binders.iter(Interner).map(|x| match &x.kind {
+ chalk_ir::VariableKind::Ty(_) => {
+ GenericArgData::Ty(table.new_type_var()).intern(Interner)
+ }
+ chalk_ir::VariableKind::Lifetime => {
+ GenericArgData::Ty(table.new_type_var()).intern(Interner)
+ } // FIXME: maybe wrong?
+ chalk_ir::VariableKind::Const(ty) => {
+ GenericArgData::Const(table.new_const_var(ty.clone())).intern(Interner)
+ }
+ }),
);
let ty1_with_vars = vars.apply(tys.value.0.clone(), Interner);
let ty2_with_vars = vars.apply(tys.value.1.clone(), Interner);
@@ -117,8 +124,7 @@ pub(crate) fn unify(
};
Some(Substitution::from_iter(
Interner,
- vars.iter(Interner)
- .map(|v| table.resolve_with_fallback(v.assert_ty_ref(Interner).clone(), &fallback)),
+ vars.iter(Interner).map(|v| table.resolve_with_fallback(v.clone(), &fallback)),
))
}
@@ -552,11 +558,18 @@ impl<'a> InferenceTable<'a> {
let mut arg_tys = vec![];
let arg_ty = TyBuilder::tuple(num_args)
- .fill(iter::repeat_with(|| {
- let arg = self.new_type_var();
+ .fill(|x| {
+ let arg = match x {
+ ParamKind::Type => self.new_type_var(),
+ ParamKind::Const(ty) => {
+ never!("Tuple with const parameter");
+ return GenericArgData::Const(self.new_const_var(ty.clone()))
+ .intern(Interner);
+ }
+ };
arg_tys.push(arg.clone());
- arg
- }))
+ GenericArgData::Ty(arg).intern(Interner)
+ })
.build();
let projection = {