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.rs | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs index b735a11adf..21b962a48f 100644 --- a/crates/hir-ty/src/infer/unify.rs +++ b/crates/hir-ty/src/infer/unify.rs @@ -15,11 +15,11 @@ use triomphe::Arc; use super::{InferOk, InferResult, InferenceContext, TypeError}; use crate::{ - db::HirDatabase, fold_tys, fold_tys_and_consts, static_lifetime, to_chalk_trait_id, - traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue, DebruijnIndex, - GenericArg, GenericArgData, Goal, Guidance, InEnvironment, InferenceVar, Interner, Lifetime, - ParamKind, ProjectionTy, ProjectionTyExt, Scalar, Solution, Substitution, TraitEnvironment, Ty, - TyBuilder, TyExt, TyKind, VariableKind, + db::HirDatabase, fold_tys_and_consts, static_lifetime, to_chalk_trait_id, traits::FnTrait, + AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue, 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> { @@ -236,13 +236,36 @@ impl<'a> InferenceTable<'a> { where T: HasInterner<Interner = Interner> + TypeFoldable<Interner>, { - fold_tys( + fold_tys_and_consts( ty, - |ty, _| match ty.kind(Interner) { - TyKind::Alias(AliasTy::Projection(proj_ty)) => { - self.normalize_projection_ty(proj_ty.clone()) - } - _ => ty, + |e, _| match e { + Either::Left(ty) => Either::Left(match ty.kind(Interner) { + TyKind::Alias(AliasTy::Projection(proj_ty)) => { + self.normalize_projection_ty(proj_ty.clone()) + } + _ => ty, + }), + Either::Right(c) => Either::Right(match &c.data(Interner).value { + chalk_ir::ConstValue::Concrete(cc) => match &cc.interned { + crate::ConstScalar::UnevaluatedConst(c_id, subst) => { + // FIXME: Ideally here we should do everything that we do with type alias, i.e. adding a variable + // and registering an obligation. But it needs chalk support, so we handle the most basic + // case (a non associated const without generic parameters) manually. + if subst.len(Interner) == 0 { + if let Ok(eval) = self.db.const_eval((*c_id).into(), subst.clone()) + { + eval + } else { + c + } + } else { + c + } + } + _ => c, + }, + _ => c, + }), }, DebruijnIndex::INNERMOST, ) |