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.rs45
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,
)