Fix another panic

This commit is contained in:
Florian Diebold 2021-05-15 23:09:18 +02:00
parent 29266ada04
commit a3d9cac690

View File

@ -3,7 +3,8 @@
use std::{borrow::Cow, fmt, sync::Arc}; use std::{borrow::Cow, fmt, sync::Arc};
use chalk_ir::{ use chalk_ir::{
cast::Cast, fold::Fold, interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, cast::Cast, fold::Fold, interner::HasInterner, zip::Zip, FloatTy, IntTy, TyVariableKind,
UniverseIndex,
}; };
use chalk_solve::infer::ParameterEnaVariableExt; use chalk_solve::infer::ParameterEnaVariableExt;
use ena::unify::UnifyKey; use ena::unify::UnifyKey;
@ -43,10 +44,7 @@ where
impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty {
crate::fold_free_vars(ty, |bound, _binders| { chalk_ir::Substitute::apply(&self.free_vars, ty, &Interner)
let var = self.free_vars[bound.index].clone();
var.assert_ty_ref(&Interner).clone()
})
} }
pub(super) fn apply_solution( pub(super) fn apply_solution(
@ -72,16 +70,16 @@ impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
_ => panic!("const variable in solution"), _ => panic!("const variable in solution"),
}), }),
); );
for (i, ty) in solution.value.iter(&Interner).enumerate() { for (i, v) in solution.value.iter(&Interner).enumerate() {
// FIXME: deal with non-type vars here -- the only problematic part is the normalization
// and maybe we don't need that with lazy normalization?
let var = self.free_vars[i].clone(); let var = self.free_vars[i].clone();
if let Some(ty) = v.ty(&Interner) {
// eagerly replace projections in the type; we may be getting types // eagerly replace projections in the type; we may be getting types
// e.g. from where clauses where this hasn't happened yet // e.g. from where clauses where this hasn't happened yet
let ty = ctx.normalize_associated_types_in( let ty = ctx.normalize_associated_types_in(new_vars.apply(ty.clone(), &Interner));
new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner),
);
ctx.table.unify(var.assert_ty_ref(&Interner), &ty); ctx.table.unify(var.assert_ty_ref(&Interner), &ty);
} else {
let _ = ctx.table.unify_inner(&var, &new_vars.apply(v.clone(), &Interner));
}
} }
} }
} }
@ -288,14 +286,14 @@ impl<'a> InferenceTable<'a> {
/// Unify two types and return new trait goals arising from it, so the /// Unify two types and return new trait goals arising from it, so the
/// caller needs to deal with them. /// caller needs to deal with them.
pub(crate) fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty) -> InferResult { pub(crate) fn unify_inner<T: Zip<Interner>>(&mut self, t1: &T, t2: &T) -> InferResult {
match self.var_unification_table.relate( match self.var_unification_table.relate(
&Interner, &Interner,
&self.db, &self.db,
&self.trait_env.env, &self.trait_env.env,
chalk_ir::Variance::Invariant, chalk_ir::Variance::Invariant,
ty1, t1,
ty2, t2,
) { ) {
Ok(_result) => { Ok(_result) => {
// TODO deal with new goals // TODO deal with new goals