aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_ty/src/infer/unify.rs19
-rw-r--r--crates/hir_ty/src/lib.rs26
-rw-r--r--crates/hir_ty/src/lower.rs26
-rw-r--r--crates/hir_ty/src/method_resolution.rs29
4 files changed, 53 insertions, 47 deletions
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 3732d8ebd..c3d9e81c3 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -118,21 +118,10 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
118 118
119impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { 119impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
120 pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { 120 pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty {
121 ty.fold_binders( 121 crate::fold_free_vars(ty, |bound, _binders| {
122 &mut |ty, binders| { 122 let (v, k) = self.free_vars[bound.index];
123 if let TyKind::BoundVar(bound) = ty.kind(&Interner) { 123 TyKind::InferenceVar(v, k).intern(&Interner)
124 if bound.debruijn >= binders { 124 })
125 let (v, k) = self.free_vars[bound.index];
126 TyKind::InferenceVar(v, k).intern(&Interner)
127 } else {
128 ty
129 }
130 } else {
131 ty
132 }
133 },
134 DebruijnIndex::INNERMOST,
135 )
136 } 125 }
137 126
138 pub(super) fn apply_solution( 127 pub(super) fn apply_solution(
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 7d4793c2f..60680ec86 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -302,3 +302,29 @@ pub fn dummy_usize_const() -> Const {
302 } 302 }
303 .intern(&Interner) 303 .intern(&Interner)
304} 304}
305
306pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + Fold<Interner>>(
307 t: T,
308 f: impl FnMut(BoundVar, DebruijnIndex) -> Ty,
309) -> T::Result {
310 use chalk_ir::{fold::Folder, Fallible};
311 struct FreeVarFolder<F>(F);
312 impl<'i, F: FnMut(BoundVar, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for FreeVarFolder<F> {
313 fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> {
314 self
315 }
316
317 fn interner(&self) -> &'i Interner {
318 &Interner
319 }
320
321 fn fold_free_var_ty(
322 &mut self,
323 bound_var: BoundVar,
324 outer_binder: DebruijnIndex,
325 ) -> Fallible<Ty> {
326 Ok(self.0(bound_var, outer_binder))
327 }
328 }
329 t.fold_with(&mut FreeVarFolder(f), DebruijnIndex::INNERMOST).expect("fold failed unexpectedly")
330}
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index b45e811fa..109157a5e 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -1016,22 +1016,16 @@ pub(crate) fn generic_defaults_query(
1016 p.default.as_ref().map_or(TyKind::Error.intern(&Interner), |t| ctx.lower_ty(t)); 1016 p.default.as_ref().map_or(TyKind::Error.intern(&Interner), |t| ctx.lower_ty(t));
1017 1017
1018 // Each default can only refer to previous parameters. 1018 // Each default can only refer to previous parameters.
1019 ty = ty.fold_binders( 1019 ty = crate::fold_free_vars(ty, |bound, binders| {
1020 &mut |ty, binders| match ty.kind(&Interner) { 1020 if bound.index >= idx && bound.debruijn == DebruijnIndex::INNERMOST {
1021 TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { 1021 // type variable default referring to parameter coming
1022 if *index >= idx { 1022 // after it. This is forbidden (FIXME: report
1023 // type variable default referring to parameter coming 1023 // diagnostic)
1024 // after it. This is forbidden (FIXME: report 1024 TyKind::Error.intern(&Interner)
1025 // diagnostic) 1025 } else {
1026 TyKind::Error.intern(&Interner) 1026 bound.shifted_in_from(binders).to_ty(&Interner)
1027 } else { 1027 }
1028 ty 1028 });
1029 }
1030 }
1031 _ => ty,
1032 },
1033 DebruijnIndex::INNERMOST,
1034 );
1035 1029
1036 crate::make_only_type_binders(idx, ty) 1030 crate::make_only_type_binders(idx, ty)
1037 }) 1031 })
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 7e09a1539..766880b14 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -6,7 +6,11 @@ use std::{iter, sync::Arc};
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; 9use chalk_ir::{
10 cast::Cast,
11 fold::{Fold, Folder},
12 Fallible, Mutability, UniverseIndex,
13};
10use hir_def::{ 14use hir_def::{
11 lang_item::LangItemTarget, nameres::DefMap, AssocContainerId, AssocItemId, FunctionId, 15 lang_item::LangItemTarget, nameres::DefMap, AssocContainerId, AssocItemId, FunctionId,
12 GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, 16 GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId,
@@ -21,7 +25,7 @@ use crate::{
21 primitive::{self, FloatTy, IntTy, UintTy}, 25 primitive::{self, FloatTy, IntTy, UintTy},
22 static_lifetime, 26 static_lifetime,
23 utils::all_super_traits, 27 utils::all_super_traits,
24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, 28 AdtId, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId,
25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, 29 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder,
26 TyExt, TyKind, TypeWalk, 30 TyExt, TyKind, TypeWalk,
27}; 31};
@@ -757,20 +761,13 @@ pub(crate) fn inherent_impl_substs(
757/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 761/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
758/// num_vars_to_keep) by `TyKind::Unknown`. 762/// num_vars_to_keep) by `TyKind::Unknown`.
759fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { 763fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
760 s.fold_binders( 764 crate::fold_free_vars(s, |bound, binders| {
761 &mut |ty, binders| { 765 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
762 if let TyKind::BoundVar(bound) = ty.kind(&Interner) { 766 TyKind::Error.intern(&Interner)
763 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 767 } else {
764 TyKind::Error.intern(&Interner) 768 bound.shifted_in_from(binders).to_ty(&Interner)
765 } else { 769 }
766 ty 770 })
767 }
768 } else {
769 ty
770 }
771 },
772 DebruijnIndex::INNERMOST,
773 )
774} 771}
775 772
776fn transform_receiver_ty( 773fn transform_receiver_ty(