diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 28cb32ac5..5d5bde305 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -879,11 +879,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
879 | ty | 879 | ty |
880 | } | 880 | } |
881 | 881 | ||
882 | fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs) -> bool { | 882 | fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool { |
883 | substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify(t1, t2)) | 883 | substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) |
884 | } | 884 | } |
885 | 885 | ||
886 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { | 886 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { |
887 | self.unify_inner(ty1, ty2, 0) | ||
888 | } | ||
889 | |||
890 | fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { | ||
891 | if depth > 1000 { | ||
892 | // prevent stackoverflows | ||
893 | panic!("infinite recursion in unification"); | ||
894 | } | ||
895 | if ty1 == ty2 { | ||
896 | return true; | ||
897 | } | ||
887 | // try to resolve type vars first | 898 | // try to resolve type vars first |
888 | let ty1 = self.resolve_ty_shallow(ty1); | 899 | let ty1 = self.resolve_ty_shallow(ty1); |
889 | let ty2 = self.resolve_ty_shallow(ty2); | 900 | let ty2 = self.resolve_ty_shallow(ty2); |
@@ -904,13 +915,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
904 | ( | 915 | ( |
905 | Ty::Adt { def_id: def_id1, substs: substs1, .. }, | 916 | Ty::Adt { def_id: def_id1, substs: substs1, .. }, |
906 | Ty::Adt { def_id: def_id2, substs: substs2, .. }, | 917 | Ty::Adt { def_id: def_id2, substs: substs2, .. }, |
907 | ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2), | 918 | ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2, depth + 1), |
908 | (Ty::Slice(t1), Ty::Slice(t2)) => self.unify(t1, t2), | 919 | (Ty::Slice(t1), Ty::Slice(t2)) => self.unify_inner(t1, t2, depth + 1), |
909 | (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => self.unify(t1, t2), | 920 | (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => { |
910 | (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify(t1, t2), | 921 | self.unify_inner(t1, t2, depth + 1) |
922 | } | ||
923 | (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify_inner(t1, t2, depth + 1), | ||
911 | (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, | 924 | (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, |
912 | (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => { | 925 | (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => { |
913 | ts1.iter().zip(ts2.iter()).all(|(t1, t2)| self.unify(t1, t2)) | 926 | ts1.iter().zip(ts2.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth + 1)) |
914 | } | 927 | } |
915 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) | 928 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) |
916 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | 929 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) |