diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 64 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 221 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 92 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/path.rs | 39 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 266 |
5 files changed, 364 insertions, 318 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 9c62932b1..1f463a425 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -7,9 +7,7 @@ | |||
7 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; | 7 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | 8 | use hir_def::lang_item::LangItemTarget; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{autoderef, Canonical, Interner, Solution, Ty, TyBuilder, TyExt, TyKind}; |
11 | autoderef, to_chalk_trait_id, traits::Solution, Interner, Substitution, TraitRef, Ty, TyKind, | ||
12 | }; | ||
13 | 11 | ||
14 | use super::{InEnvironment, InferenceContext}; | 12 | use super::{InEnvironment, InferenceContext}; |
15 | 13 | ||
@@ -36,7 +34,7 @@ impl<'a> InferenceContext<'a> { | |||
36 | ty1.clone() | 34 | ty1.clone() |
37 | } else { | 35 | } else { |
38 | if let (TyKind::FnDef(..), TyKind::FnDef(..)) = | 36 | if let (TyKind::FnDef(..), TyKind::FnDef(..)) = |
39 | (ty1.interned(&Interner), ty2.interned(&Interner)) | 37 | (ty1.kind(&Interner), ty2.kind(&Interner)) |
40 | { | 38 | { |
41 | cov_mark::hit!(coerce_fn_reification); | 39 | cov_mark::hit!(coerce_fn_reification); |
42 | // Special case: two function types. Try to coerce both to | 40 | // Special case: two function types. Try to coerce both to |
@@ -44,8 +42,8 @@ impl<'a> InferenceContext<'a> { | |||
44 | // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 | 42 | // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 |
45 | let sig1 = ty1.callable_sig(self.db).expect("FnDef without callable sig"); | 43 | let sig1 = ty1.callable_sig(self.db).expect("FnDef without callable sig"); |
46 | let sig2 = ty2.callable_sig(self.db).expect("FnDef without callable sig"); | 44 | let sig2 = ty2.callable_sig(self.db).expect("FnDef without callable sig"); |
47 | let ptr_ty1 = Ty::fn_ptr(sig1); | 45 | let ptr_ty1 = TyBuilder::fn_ptr(sig1); |
48 | let ptr_ty2 = Ty::fn_ptr(sig2); | 46 | let ptr_ty2 = TyBuilder::fn_ptr(sig2); |
49 | self.coerce_merge_branch(&ptr_ty1, &ptr_ty2) | 47 | self.coerce_merge_branch(&ptr_ty1, &ptr_ty2) |
50 | } else { | 48 | } else { |
51 | cov_mark::hit!(coerce_merge_fail_fallback); | 49 | cov_mark::hit!(coerce_merge_fail_fallback); |
@@ -55,7 +53,7 @@ impl<'a> InferenceContext<'a> { | |||
55 | } | 53 | } |
56 | 54 | ||
57 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { | 55 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { |
58 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { | 56 | match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { |
59 | // Never type will make type variable to fallback to Never Type instead of Unknown. | 57 | // Never type will make type variable to fallback to Never Type instead of Unknown. |
60 | (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => { | 58 | (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => { |
61 | self.table.type_variable_table.set_diverging(*tv, true); | 59 | self.table.type_variable_table.set_diverging(*tv, true); |
@@ -73,17 +71,19 @@ impl<'a> InferenceContext<'a> { | |||
73 | } | 71 | } |
74 | 72 | ||
75 | // Pointer weakening and function to pointer | 73 | // Pointer weakening and function to pointer |
76 | match (from_ty.interned_mut(), to_ty.interned(&Interner)) { | 74 | match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { |
77 | // `*mut T` -> `*const T` | 75 | // `*mut T` -> `*const T` |
76 | (TyKind::Raw(_, inner), TyKind::Raw(m2 @ Mutability::Not, ..)) => { | ||
77 | from_ty = TyKind::Raw(*m2, inner.clone()).intern(&Interner); | ||
78 | } | ||
78 | // `&mut T` -> `&T` | 79 | // `&mut T` -> `&T` |
79 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) | 80 | (TyKind::Ref(_, lt, inner), TyKind::Ref(m2 @ Mutability::Not, ..)) => { |
80 | | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => { | 81 | from_ty = TyKind::Ref(*m2, lt.clone(), inner.clone()).intern(&Interner); |
81 | *m1 = *m2; | ||
82 | } | 82 | } |
83 | // `&T` -> `*const T` | 83 | // `&T` -> `*const T` |
84 | // `&mut T` -> `*mut T`/`*const T` | 84 | // `&mut T` -> `*mut T`/`*const T` |
85 | (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) | 85 | (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) |
86 | | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => { | 86 | | (TyKind::Ref(Mutability::Mut, _, substs), &TyKind::Raw(m2, ..)) => { |
87 | from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); | 87 | from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); |
88 | } | 88 | } |
89 | 89 | ||
@@ -95,12 +95,12 @@ impl<'a> InferenceContext<'a> { | |||
95 | (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { | 95 | (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { |
96 | None => return false, | 96 | None => return false, |
97 | Some(sig) => { | 97 | Some(sig) => { |
98 | from_ty = Ty::fn_ptr(sig); | 98 | from_ty = TyBuilder::fn_ptr(sig); |
99 | } | 99 | } |
100 | }, | 100 | }, |
101 | 101 | ||
102 | (TyKind::Closure(.., substs), TyKind::Function { .. }) => { | 102 | (TyKind::Closure(.., substs), TyKind::Function { .. }) => { |
103 | from_ty = substs[0].clone(); | 103 | from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone(); |
104 | } | 104 | } |
105 | 105 | ||
106 | _ => {} | 106 | _ => {} |
@@ -111,9 +111,11 @@ impl<'a> InferenceContext<'a> { | |||
111 | } | 111 | } |
112 | 112 | ||
113 | // Auto Deref if cannot coerce | 113 | // Auto Deref if cannot coerce |
114 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { | 114 | match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { |
115 | // FIXME: DerefMut | 115 | // FIXME: DerefMut |
116 | (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), | 116 | (TyKind::Ref(.., st1), TyKind::Ref(.., st2)) => { |
117 | self.unify_autoderef_behind_ref(st1, st2) | ||
118 | } | ||
117 | 119 | ||
118 | // Otherwise, normal unify | 120 | // Otherwise, normal unify |
119 | _ => self.unify(&from_ty, to_ty), | 121 | _ => self.unify(&from_ty, to_ty), |
@@ -130,19 +132,16 @@ impl<'a> InferenceContext<'a> { | |||
130 | _ => return None, | 132 | _ => return None, |
131 | }; | 133 | }; |
132 | 134 | ||
133 | let generic_params = crate::utils::generics(self.db.upcast(), coerce_unsized_trait.into()); | 135 | let trait_ref = { |
134 | if generic_params.len() != 2 { | 136 | let b = TyBuilder::trait_ref(self.db, coerce_unsized_trait); |
135 | // The CoerceUnsized trait should have two generic params: Self and T. | 137 | if b.remaining() != 2 { |
136 | return None; | 138 | // The CoerceUnsized trait should have two generic params: Self and T. |
137 | } | 139 | return None; |
140 | } | ||
141 | b.push(from_ty.clone()).push(to_ty.clone()).build() | ||
142 | }; | ||
138 | 143 | ||
139 | let substs = Substitution::build_for_generics(&generic_params) | 144 | let goal = InEnvironment::new(&self.trait_env.env, trait_ref.cast(&Interner)); |
140 | .push(from_ty.clone()) | ||
141 | .push(to_ty.clone()) | ||
142 | .build(); | ||
143 | let trait_ref = | ||
144 | TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs }; | ||
145 | let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner)); | ||
146 | 145 | ||
147 | let canonicalizer = self.canonicalizer(); | 146 | let canonicalizer = self.canonicalizer(); |
148 | let canonicalized = canonicalizer.canonicalize_obligation(goal); | 147 | let canonicalized = canonicalizer.canonicalize_obligation(goal); |
@@ -151,7 +150,14 @@ impl<'a> InferenceContext<'a> { | |||
151 | 150 | ||
152 | match solution { | 151 | match solution { |
153 | Solution::Unique(v) => { | 152 | Solution::Unique(v) => { |
154 | canonicalized.apply_solution(self, v.0); | 153 | canonicalized.apply_solution( |
154 | self, | ||
155 | Canonical { | ||
156 | binders: v.binders, | ||
157 | // FIXME handle constraints | ||
158 | value: v.value.subst, | ||
159 | }, | ||
160 | ); | ||
155 | } | 161 | } |
156 | _ => return None, | 162 | _ => return None, |
157 | }; | 163 | }; |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index e6ede05ca..50497eecb 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::iter::{repeat, repeat_with}; | 3 | use std::iter::{repeat, repeat_with}; |
4 | use std::{mem, sync::Arc}; | 4 | use std::{mem, sync::Arc}; |
5 | 5 | ||
6 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; | 6 | use chalk_ir::{cast::Cast, fold::Shift, Mutability, TyVariableKind}; |
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
9 | path::{GenericArg, GenericArgs}, | 9 | path::{GenericArg, GenericArgs}, |
@@ -15,15 +15,16 @@ use stdx::always; | |||
15 | use syntax::ast::RangeOp; | 15 | use syntax::ast::RangeOp; |
16 | 16 | ||
17 | use crate::{ | 17 | use crate::{ |
18 | autoderef, | 18 | autoderef, dummy_usize_const, |
19 | lower::lower_to_chalk_mutability, | 19 | lower::lower_to_chalk_mutability, |
20 | mapping::from_chalk, | ||
20 | method_resolution, op, | 21 | method_resolution, op, |
21 | primitive::{self, UintTy}, | 22 | primitive::{self, UintTy}, |
22 | to_assoc_type_id, to_chalk_trait_id, | 23 | static_lifetime, to_chalk_trait_id, |
23 | traits::{chalk::from_chalk, FnTrait, InEnvironment}, | 24 | traits::FnTrait, |
24 | utils::{generics, variant_data, Generics}, | 25 | utils::{generics, Generics}, |
25 | AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar, | 26 | AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner, |
26 | Substitution, TraitRef, Ty, TyKind, | 27 | ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind, |
27 | }; | 28 | }; |
28 | 29 | ||
29 | use super::{ | 30 | use super::{ |
@@ -73,38 +74,33 @@ impl<'a> InferenceContext<'a> { | |||
73 | let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; | 74 | let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; |
74 | let output_assoc_type = | 75 | let output_assoc_type = |
75 | self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; | 76 | self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; |
76 | let generic_params = generics(self.db.upcast(), fn_once_trait.into()); | ||
77 | if generic_params.len() != 2 { | ||
78 | return None; | ||
79 | } | ||
80 | 77 | ||
81 | let mut param_builder = Substitution::builder(num_args); | ||
82 | let mut arg_tys = vec![]; | 78 | let mut arg_tys = vec![]; |
83 | for _ in 0..num_args { | 79 | let arg_ty = TyBuilder::tuple(num_args) |
84 | let arg = self.table.new_type_var(); | 80 | .fill(repeat_with(|| { |
85 | param_builder = param_builder.push(arg.clone()); | 81 | let arg = self.table.new_type_var(); |
86 | arg_tys.push(arg); | 82 | arg_tys.push(arg.clone()); |
87 | } | 83 | arg |
88 | let parameters = param_builder.build(); | 84 | })) |
89 | let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); | 85 | .build(); |
90 | let substs = | 86 | |
91 | Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 87 | let projection = { |
88 | let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type); | ||
89 | if b.remaining() != 2 { | ||
90 | return None; | ||
91 | } | ||
92 | b.push(ty.clone()).push(arg_ty).build() | ||
93 | }; | ||
92 | 94 | ||
93 | let trait_env = self.trait_env.env.clone(); | 95 | let trait_env = self.trait_env.env.clone(); |
94 | let implements_fn_trait: DomainGoal = | 96 | let obligation = InEnvironment { |
95 | TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } | 97 | goal: projection.trait_ref(self.db).cast(&Interner), |
96 | .cast(&Interner); | ||
97 | let goal = self.canonicalizer().canonicalize_obligation(InEnvironment { | ||
98 | goal: implements_fn_trait.clone(), | ||
99 | environment: trait_env, | 98 | environment: trait_env, |
100 | }); | 99 | }; |
101 | if self.db.trait_solve(krate, goal.value).is_some() { | 100 | let canonical = self.canonicalizer().canonicalize_obligation(obligation.clone()); |
102 | self.obligations.push(implements_fn_trait); | 101 | if self.db.trait_solve(krate, canonical.value).is_some() { |
103 | let output_proj_ty = crate::ProjectionTy { | 102 | self.push_obligation(obligation.goal); |
104 | associated_ty_id: to_assoc_type_id(output_assoc_type), | 103 | let return_ty = self.normalize_projection_ty(projection); |
105 | substitution: substs, | ||
106 | }; | ||
107 | let return_ty = self.normalize_projection_ty(output_proj_ty); | ||
108 | Some((arg_tys, return_ty)) | 104 | Some((arg_tys, return_ty)) |
109 | } else { | 105 | } else { |
110 | None | 106 | None |
@@ -119,6 +115,8 @@ impl<'a> InferenceContext<'a> { | |||
119 | } | 115 | } |
120 | 116 | ||
121 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { | 117 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
118 | self.db.check_canceled(); | ||
119 | |||
122 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 120 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
123 | let ty = match &body[tgt_expr] { | 121 | let ty = match &body[tgt_expr] { |
124 | Expr::Missing => self.err_ty(), | 122 | Expr::Missing => self.err_ty(), |
@@ -136,7 +134,7 @@ impl<'a> InferenceContext<'a> { | |||
136 | both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); | 134 | both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); |
137 | let else_ty = match else_branch { | 135 | let else_ty = match else_branch { |
138 | Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), | 136 | Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), |
139 | None => Ty::unit(), | 137 | None => TyBuilder::unit(), |
140 | }; | 138 | }; |
141 | both_arms_diverge &= self.diverges; | 139 | both_arms_diverge &= self.diverges; |
142 | 140 | ||
@@ -183,7 +181,8 @@ impl<'a> InferenceContext<'a> { | |||
183 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 181 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
184 | let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); | 182 | let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); |
185 | let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); | 183 | let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); |
186 | TyKind::OpaqueType(opaque_ty_id, Substitution::single(inner_ty)).intern(&Interner) | 184 | TyKind::OpaqueType(opaque_ty_id, Substitution::from1(&Interner, inner_ty)) |
185 | .intern(&Interner) | ||
187 | } | 186 | } |
188 | Expr::Loop { body, label } => { | 187 | Expr::Loop { body, label } => { |
189 | self.breakables.push(BreakableContext { | 188 | self.breakables.push(BreakableContext { |
@@ -191,7 +190,7 @@ impl<'a> InferenceContext<'a> { | |||
191 | break_ty: self.table.new_type_var(), | 190 | break_ty: self.table.new_type_var(), |
192 | label: label.map(|label| self.body[label].name.clone()), | 191 | label: label.map(|label| self.body[label].name.clone()), |
193 | }); | 192 | }); |
194 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 193 | self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit())); |
195 | 194 | ||
196 | let ctxt = self.breakables.pop().expect("breakable stack broken"); | 195 | let ctxt = self.breakables.pop().expect("breakable stack broken"); |
197 | if ctxt.may_break { | 196 | if ctxt.may_break { |
@@ -215,11 +214,11 @@ impl<'a> InferenceContext<'a> { | |||
215 | *condition, | 214 | *condition, |
216 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), | 215 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), |
217 | ); | 216 | ); |
218 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 217 | self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit())); |
219 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 218 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
220 | // the body may not run, so it diverging doesn't mean we diverge | 219 | // the body may not run, so it diverging doesn't mean we diverge |
221 | self.diverges = Diverges::Maybe; | 220 | self.diverges = Diverges::Maybe; |
222 | Ty::unit() | 221 | TyBuilder::unit() |
223 | } | 222 | } |
224 | Expr::For { iterable, body, pat, label } => { | 223 | Expr::For { iterable, body, pat, label } => { |
225 | let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 224 | let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
@@ -234,11 +233,11 @@ impl<'a> InferenceContext<'a> { | |||
234 | 233 | ||
235 | self.infer_pat(*pat, &pat_ty, BindingMode::default()); | 234 | self.infer_pat(*pat, &pat_ty, BindingMode::default()); |
236 | 235 | ||
237 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 236 | self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit())); |
238 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 237 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
239 | // the body may not run, so it diverging doesn't mean we diverge | 238 | // the body may not run, so it diverging doesn't mean we diverge |
240 | self.diverges = Diverges::Maybe; | 239 | self.diverges = Diverges::Maybe; |
241 | Ty::unit() | 240 | TyBuilder::unit() |
242 | } | 241 | } |
243 | Expr::Lambda { body, args, ret_type, arg_types } => { | 242 | Expr::Lambda { body, args, ret_type, arg_types } => { |
244 | assert_eq!(args.len(), arg_types.len()); | 243 | assert_eq!(args.len(), arg_types.len()); |
@@ -262,14 +261,17 @@ impl<'a> InferenceContext<'a> { | |||
262 | }; | 261 | }; |
263 | sig_tys.push(ret_ty.clone()); | 262 | sig_tys.push(ret_ty.clone()); |
264 | let sig_ty = TyKind::Function(FnPointer { | 263 | let sig_ty = TyKind::Function(FnPointer { |
265 | num_args: sig_tys.len() - 1, | 264 | num_binders: 0, |
266 | sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, | 265 | sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, |
267 | substs: Substitution(sig_tys.clone().into()), | 266 | substitution: FnSubst( |
267 | Substitution::from_iter(&Interner, sig_tys.clone()).shifted_in(&Interner), | ||
268 | ), | ||
268 | }) | 269 | }) |
269 | .intern(&Interner); | 270 | .intern(&Interner); |
270 | let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); | 271 | let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); |
271 | let closure_ty = | 272 | let closure_ty = |
272 | TyKind::Closure(closure_id, Substitution::single(sig_ty)).intern(&Interner); | 273 | TyKind::Closure(closure_id, Substitution::from1(&Interner, sig_ty)) |
274 | .intern(&Interner); | ||
273 | 275 | ||
274 | // Eagerly try to relate the closure type with the expected | 276 | // Eagerly try to relate the closure type with the expected |
275 | // type, otherwise we often won't have enough information to | 277 | // type, otherwise we often won't have enough information to |
@@ -316,7 +318,13 @@ impl<'a> InferenceContext<'a> { | |||
316 | self.normalize_associated_types_in(ret_ty) | 318 | self.normalize_associated_types_in(ret_ty) |
317 | } | 319 | } |
318 | Expr::MethodCall { receiver, args, method_name, generic_args } => self | 320 | Expr::MethodCall { receiver, args, method_name, generic_args } => self |
319 | .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()), | 321 | .infer_method_call( |
322 | tgt_expr, | ||
323 | *receiver, | ||
324 | &args, | ||
325 | &method_name, | ||
326 | generic_args.as_deref(), | ||
327 | ), | ||
320 | Expr::Match { expr, arms } => { | 328 | Expr::Match { expr, arms } => { |
321 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 329 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
322 | 330 | ||
@@ -358,7 +366,7 @@ impl<'a> InferenceContext<'a> { | |||
358 | let val_ty = if let Some(expr) = expr { | 366 | let val_ty = if let Some(expr) = expr { |
359 | self.infer_expr(*expr, &Expectation::none()) | 367 | self.infer_expr(*expr, &Expectation::none()) |
360 | } else { | 368 | } else { |
361 | Ty::unit() | 369 | TyBuilder::unit() |
362 | }; | 370 | }; |
363 | 371 | ||
364 | let last_ty = | 372 | let last_ty = |
@@ -384,7 +392,7 @@ impl<'a> InferenceContext<'a> { | |||
384 | if let Some(expr) = expr { | 392 | if let Some(expr) = expr { |
385 | self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); | 393 | self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); |
386 | } else { | 394 | } else { |
387 | let unit = Ty::unit(); | 395 | let unit = TyBuilder::unit(); |
388 | self.coerce(&unit, &self.return_ty.clone()); | 396 | self.coerce(&unit, &self.return_ty.clone()); |
389 | } | 397 | } |
390 | TyKind::Never.intern(&Interner) | 398 | TyKind::Never.intern(&Interner) |
@@ -397,16 +405,19 @@ impl<'a> InferenceContext<'a> { | |||
397 | TyKind::Never.intern(&Interner) | 405 | TyKind::Never.intern(&Interner) |
398 | } | 406 | } |
399 | Expr::RecordLit { path, fields, spread } => { | 407 | Expr::RecordLit { path, fields, spread } => { |
400 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 408 | let (ty, def_id) = self.resolve_variant(path.as_deref()); |
401 | if let Some(variant) = def_id { | 409 | if let Some(variant) = def_id { |
402 | self.write_variant_resolution(tgt_expr.into(), variant); | 410 | self.write_variant_resolution(tgt_expr.into(), variant); |
403 | } | 411 | } |
404 | 412 | ||
405 | self.unify(&ty, &expected.ty); | 413 | self.unify(&ty, &expected.ty); |
406 | 414 | ||
407 | let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); | 415 | let substs = ty |
416 | .as_adt() | ||
417 | .map(|(_, s)| s.clone()) | ||
418 | .unwrap_or_else(|| Substitution::empty(&Interner)); | ||
408 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); | 419 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); |
409 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); | 420 | let variant_data = def_id.map(|it| it.variant_data(self.db.upcast())); |
410 | for field in fields.iter() { | 421 | for field in fields.iter() { |
411 | let field_def = | 422 | let field_def = |
412 | variant_data.as_ref().and_then(|it| match it.field(&field.name) { | 423 | variant_data.as_ref().and_then(|it| match it.field(&field.name) { |
@@ -418,11 +429,8 @@ impl<'a> InferenceContext<'a> { | |||
418 | None | 429 | None |
419 | } | 430 | } |
420 | }); | 431 | }); |
421 | if let Some(field_def) = field_def { | ||
422 | self.result.record_field_resolutions.insert(field.expr, field_def); | ||
423 | } | ||
424 | let field_ty = field_def.map_or(self.err_ty(), |it| { | 432 | let field_ty = field_def.map_or(self.err_ty(), |it| { |
425 | field_types[it.local_id].clone().subst(&substs) | 433 | field_types[it.local_id].clone().substitute(&Interner, &substs) |
426 | }); | 434 | }); |
427 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); | 435 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
428 | } | 436 | } |
@@ -453,10 +461,14 @@ impl<'a> InferenceContext<'a> { | |||
453 | }) | 461 | }) |
454 | .unwrap_or(true) | 462 | .unwrap_or(true) |
455 | }; | 463 | }; |
456 | match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { | 464 | match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) { |
457 | TyKind::Tuple(_, substs) => { | 465 | TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| { |
458 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) | 466 | substs |
459 | } | 467 | .as_slice(&Interner) |
468 | .get(idx) | ||
469 | .map(|a| a.assert_ty_ref(&Interner)) | ||
470 | .cloned() | ||
471 | }), | ||
460 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { | 472 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { |
461 | let local_id = self.db.struct_data(*s).variant_data.field(name)?; | 473 | let local_id = self.db.struct_data(*s).variant_data.field(name)?; |
462 | let field = FieldId { parent: (*s).into(), local_id }; | 474 | let field = FieldId { parent: (*s).into(), local_id }; |
@@ -465,7 +477,7 @@ impl<'a> InferenceContext<'a> { | |||
465 | Some( | 477 | Some( |
466 | self.db.field_types((*s).into())[field.local_id] | 478 | self.db.field_types((*s).into())[field.local_id] |
467 | .clone() | 479 | .clone() |
468 | .subst(¶meters), | 480 | .substitute(&Interner, ¶meters), |
469 | ) | 481 | ) |
470 | } else { | 482 | } else { |
471 | None | 483 | None |
@@ -479,7 +491,7 @@ impl<'a> InferenceContext<'a> { | |||
479 | Some( | 491 | Some( |
480 | self.db.field_types((*u).into())[field.local_id] | 492 | self.db.field_types((*u).into())[field.local_id] |
481 | .clone() | 493 | .clone() |
482 | .subst(¶meters), | 494 | .substitute(&Interner, ¶meters), |
483 | ) | 495 | ) |
484 | } else { | 496 | } else { |
485 | None | 497 | None |
@@ -526,24 +538,17 @@ impl<'a> InferenceContext<'a> { | |||
526 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 538 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
527 | match rawness { | 539 | match rawness { |
528 | Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), | 540 | Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), |
529 | Rawness::Ref => TyKind::Ref(mutability, inner_ty), | 541 | Rawness::Ref => TyKind::Ref(mutability, static_lifetime(), inner_ty), |
530 | } | 542 | } |
531 | .intern(&Interner) | 543 | .intern(&Interner) |
532 | } | 544 | } |
533 | Expr::Box { expr } => { | 545 | Expr::Box { expr } => { |
534 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 546 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
535 | if let Some(box_) = self.resolve_boxed_box() { | 547 | if let Some(box_) = self.resolve_boxed_box() { |
536 | let mut sb = | 548 | TyBuilder::adt(self.db, box_) |
537 | Substitution::build_for_generics(&generics(self.db.upcast(), box_.into())); | 549 | .push(inner_ty) |
538 | sb = sb.push(inner_ty); | 550 | .fill_with_defaults(self.db, || self.table.new_type_var()) |
539 | match self.db.generic_defaults(box_.into()).get(1) { | 551 | .build() |
540 | Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => { | ||
541 | sb = sb.push(alloc_ty.value.clone()); | ||
542 | } | ||
543 | _ => (), | ||
544 | } | ||
545 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | ||
546 | Ty::adt_ty(box_, sb.build()) | ||
547 | } else { | 552 | } else { |
548 | self.err_ty() | 553 | self.err_ty() |
549 | } | 554 | } |
@@ -571,7 +576,7 @@ impl<'a> InferenceContext<'a> { | |||
571 | None => self.err_ty(), | 576 | None => self.err_ty(), |
572 | }, | 577 | }, |
573 | UnaryOp::Neg => { | 578 | UnaryOp::Neg => { |
574 | match inner_ty.interned(&Interner) { | 579 | match inner_ty.kind(&Interner) { |
575 | // Fast path for builtins | 580 | // Fast path for builtins |
576 | TyKind::Scalar(Scalar::Int(_)) | 581 | TyKind::Scalar(Scalar::Int(_)) |
577 | | TyKind::Scalar(Scalar::Uint(_)) | 582 | | TyKind::Scalar(Scalar::Uint(_)) |
@@ -584,7 +589,7 @@ impl<'a> InferenceContext<'a> { | |||
584 | } | 589 | } |
585 | } | 590 | } |
586 | UnaryOp::Not => { | 591 | UnaryOp::Not => { |
587 | match inner_ty.interned(&Interner) { | 592 | match inner_ty.kind(&Interner) { |
588 | // Fast path for builtins | 593 | // Fast path for builtins |
589 | TyKind::Scalar(Scalar::Bool) | 594 | TyKind::Scalar(Scalar::Bool) |
590 | | TyKind::Scalar(Scalar::Int(_)) | 595 | | TyKind::Scalar(Scalar::Int(_)) |
@@ -633,31 +638,31 @@ impl<'a> InferenceContext<'a> { | |||
633 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); | 638 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); |
634 | match (range_type, lhs_ty, rhs_ty) { | 639 | match (range_type, lhs_ty, rhs_ty) { |
635 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 640 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
636 | Some(adt) => Ty::adt_ty(adt, Substitution::empty()), | 641 | Some(adt) => TyBuilder::adt(self.db, adt).build(), |
637 | None => self.err_ty(), | 642 | None => self.err_ty(), |
638 | }, | 643 | }, |
639 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 644 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
640 | Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), | 645 | Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(), |
641 | None => self.err_ty(), | 646 | None => self.err_ty(), |
642 | }, | 647 | }, |
643 | (RangeOp::Inclusive, None, Some(ty)) => { | 648 | (RangeOp::Inclusive, None, Some(ty)) => { |
644 | match self.resolve_range_to_inclusive() { | 649 | match self.resolve_range_to_inclusive() { |
645 | Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), | 650 | Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(), |
646 | None => self.err_ty(), | 651 | None => self.err_ty(), |
647 | } | 652 | } |
648 | } | 653 | } |
649 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 654 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
650 | Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), | 655 | Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(), |
651 | None => self.err_ty(), | 656 | None => self.err_ty(), |
652 | }, | 657 | }, |
653 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 658 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
654 | match self.resolve_range_inclusive() { | 659 | match self.resolve_range_inclusive() { |
655 | Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), | 660 | Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(), |
656 | None => self.err_ty(), | 661 | None => self.err_ty(), |
657 | } | 662 | } |
658 | } | 663 | } |
659 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 664 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
660 | Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), | 665 | Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(), |
661 | None => self.err_ty(), | 666 | None => self.err_ty(), |
662 | }, | 667 | }, |
663 | (RangeOp::Inclusive, _, None) => self.err_ty(), | 668 | (RangeOp::Inclusive, _, None) => self.err_ty(), |
@@ -690,10 +695,10 @@ impl<'a> InferenceContext<'a> { | |||
690 | } | 695 | } |
691 | } | 696 | } |
692 | Expr::Tuple { exprs } => { | 697 | Expr::Tuple { exprs } => { |
693 | let mut tys = match expected.ty.interned(&Interner) { | 698 | let mut tys = match expected.ty.kind(&Interner) { |
694 | TyKind::Tuple(_, substs) => substs | 699 | TyKind::Tuple(_, substs) => substs |
695 | .iter() | 700 | .iter(&Interner) |
696 | .cloned() | 701 | .map(|a| a.assert_ty_ref(&Interner).clone()) |
697 | .chain(repeat_with(|| self.table.new_type_var())) | 702 | .chain(repeat_with(|| self.table.new_type_var())) |
698 | .take(exprs.len()) | 703 | .take(exprs.len()) |
699 | .collect::<Vec<_>>(), | 704 | .collect::<Vec<_>>(), |
@@ -704,11 +709,11 @@ impl<'a> InferenceContext<'a> { | |||
704 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 709 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
705 | } | 710 | } |
706 | 711 | ||
707 | TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner) | 712 | TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner) |
708 | } | 713 | } |
709 | Expr::Array(array) => { | 714 | Expr::Array(array) => { |
710 | let elem_ty = match expected.ty.interned(&Interner) { | 715 | let elem_ty = match expected.ty.kind(&Interner) { |
711 | TyKind::Array(st) | TyKind::Slice(st) => st.clone(), | 716 | TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(), |
712 | _ => self.table.new_type_var(), | 717 | _ => self.table.new_type_var(), |
713 | }; | 718 | }; |
714 | 719 | ||
@@ -732,17 +737,19 @@ impl<'a> InferenceContext<'a> { | |||
732 | } | 737 | } |
733 | } | 738 | } |
734 | 739 | ||
735 | TyKind::Array(elem_ty).intern(&Interner) | 740 | TyKind::Array(elem_ty, dummy_usize_const()).intern(&Interner) |
736 | } | 741 | } |
737 | Expr::Literal(lit) => match lit { | 742 | Expr::Literal(lit) => match lit { |
738 | Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), | 743 | Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
739 | Literal::String(..) => { | 744 | Literal::String(..) => { |
740 | TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) | 745 | TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(&Interner)) |
746 | .intern(&Interner) | ||
741 | } | 747 | } |
742 | Literal::ByteString(..) => { | 748 | Literal::ByteString(..) => { |
743 | let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); | 749 | let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); |
744 | let array_type = TyKind::Array(byte_type).intern(&Interner); | 750 | let array_type = |
745 | TyKind::Ref(Mutability::Not, array_type).intern(&Interner) | 751 | TyKind::Array(byte_type, dummy_usize_const()).intern(&Interner); |
752 | TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner) | ||
746 | } | 753 | } |
747 | Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), | 754 | Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), |
748 | Literal::Int(_v, ty) => match ty { | 755 | Literal::Int(_v, ty) => match ty { |
@@ -822,8 +829,8 @@ impl<'a> InferenceContext<'a> { | |||
822 | // we don't even make an attempt at coercion | 829 | // we don't even make an attempt at coercion |
823 | self.table.new_maybe_never_var() | 830 | self.table.new_maybe_never_var() |
824 | } else { | 831 | } else { |
825 | self.coerce(&Ty::unit(), &expected.coercion_target()); | 832 | self.coerce(&TyBuilder::unit(), &expected.coercion_target()); |
826 | Ty::unit() | 833 | TyBuilder::unit() |
827 | } | 834 | } |
828 | }; | 835 | }; |
829 | ty | 836 | ty |
@@ -859,10 +866,10 @@ impl<'a> InferenceContext<'a> { | |||
859 | self.write_method_resolution(tgt_expr, func); | 866 | self.write_method_resolution(tgt_expr, func); |
860 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) | 867 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) |
861 | } | 868 | } |
862 | None => (receiver_ty, Binders::new(0, self.err_ty()), None), | 869 | None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None), |
863 | }; | 870 | }; |
864 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); | 871 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); |
865 | let method_ty = method_ty.subst(&substs); | 872 | let method_ty = method_ty.substitute(&Interner, &substs); |
866 | let method_ty = self.insert_type_vars(method_ty); | 873 | let method_ty = self.insert_type_vars(method_ty); |
867 | self.register_obligations_for_call(&method_ty); | 874 | self.register_obligations_for_call(&method_ty); |
868 | let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { | 875 | let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { |
@@ -878,7 +885,9 @@ impl<'a> InferenceContext<'a> { | |||
878 | // Apply autoref so the below unification works correctly | 885 | // Apply autoref so the below unification works correctly |
879 | // FIXME: return correct autorefs from lookup_method | 886 | // FIXME: return correct autorefs from lookup_method |
880 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 887 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
881 | Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner), | 888 | Some((_, lifetime, mutability)) => { |
889 | TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner) | ||
890 | } | ||
882 | _ => derefed_receiver_ty, | 891 | _ => derefed_receiver_ty, |
883 | }; | 892 | }; |
884 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 893 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -951,18 +960,20 @@ impl<'a> InferenceContext<'a> { | |||
951 | substs.push(self.err_ty()); | 960 | substs.push(self.err_ty()); |
952 | } | 961 | } |
953 | assert_eq!(substs.len(), total_len); | 962 | assert_eq!(substs.len(), total_len); |
954 | Substitution(substs.into()) | 963 | Substitution::from_iter(&Interner, substs) |
955 | } | 964 | } |
956 | 965 | ||
957 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 966 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
958 | if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) { | 967 | if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) { |
959 | let def: CallableDefId = from_chalk(self.db, *fn_def); | 968 | let def: CallableDefId = from_chalk(self.db, *fn_def); |
960 | let generic_predicates = self.db.generic_predicates(def.into()); | 969 | let generic_predicates = self.db.generic_predicates(def.into()); |
961 | for predicate in generic_predicates.iter() { | 970 | for predicate in generic_predicates.iter() { |
962 | let (predicate, binders) = | 971 | let (predicate, binders) = predicate |
963 | predicate.clone().subst(parameters).into_value_and_skipped_binders(); | 972 | .clone() |
964 | always!(binders == 0); // quantified where clauses not yet handled | 973 | .substitute(&Interner, parameters) |
965 | self.obligations.push(predicate.cast(&Interner)); | 974 | .into_value_and_skipped_binders(); |
975 | always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled | ||
976 | self.push_obligation(predicate.cast(&Interner)); | ||
966 | } | 977 | } |
967 | // add obligation for trait implementation, if this is a trait method | 978 | // add obligation for trait implementation, if this is a trait method |
968 | match def { | 979 | match def { |
@@ -970,9 +981,11 @@ impl<'a> InferenceContext<'a> { | |||
970 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container | 981 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container |
971 | { | 982 | { |
972 | // construct a TraitRef | 983 | // construct a TraitRef |
973 | let substs = | 984 | let substs = crate::subst_prefix( |
974 | parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); | 985 | &*parameters, |
975 | self.obligations.push( | 986 | generics(self.db.upcast(), trait_.into()).len(), |
987 | ); | ||
988 | self.push_obligation( | ||
976 | TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } | 989 | TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } |
977 | .cast(&Interner), | 990 | .cast(&Interner), |
978 | ); | 991 | ); |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index 474363709..aea354cde 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -7,15 +7,13 @@ use chalk_ir::Mutability; | |||
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, | 8 | expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, |
9 | path::Path, | 9 | path::Path, |
10 | FieldId, | ||
11 | }; | 10 | }; |
12 | use hir_expand::name::Name; | 11 | use hir_expand::name::Name; |
13 | 12 | ||
14 | use super::{BindingMode, Expectation, InferenceContext}; | 13 | use super::{BindingMode, Expectation, InferenceContext}; |
15 | use crate::{ | 14 | use crate::{ |
16 | lower::lower_to_chalk_mutability, | 15 | lower::lower_to_chalk_mutability, static_lifetime, Interner, Substitution, Ty, TyBuilder, |
17 | utils::{generics, variant_data}, | 16 | TyExt, TyKind, |
18 | Interner, Substitution, Ty, TyKind, | ||
19 | }; | 17 | }; |
20 | 18 | ||
21 | impl<'a> InferenceContext<'a> { | 19 | impl<'a> InferenceContext<'a> { |
@@ -29,13 +27,14 @@ impl<'a> InferenceContext<'a> { | |||
29 | ellipsis: Option<usize>, | 27 | ellipsis: Option<usize>, |
30 | ) -> Ty { | 28 | ) -> Ty { |
31 | let (ty, def) = self.resolve_variant(path); | 29 | let (ty, def) = self.resolve_variant(path); |
32 | let var_data = def.map(|it| variant_data(self.db.upcast(), it)); | 30 | let var_data = def.map(|it| it.variant_data(self.db.upcast())); |
33 | if let Some(variant) = def { | 31 | if let Some(variant) = def { |
34 | self.write_variant_resolution(id.into(), variant); | 32 | self.write_variant_resolution(id.into(), variant); |
35 | } | 33 | } |
36 | self.unify(&ty, expected); | 34 | self.unify(&ty, expected); |
37 | 35 | ||
38 | let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); | 36 | let substs = |
37 | ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(&Interner)); | ||
39 | 38 | ||
40 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); | 39 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); |
41 | let (pre, post) = match ellipsis { | 40 | let (pre, post) = match ellipsis { |
@@ -50,7 +49,9 @@ impl<'a> InferenceContext<'a> { | |||
50 | let expected_ty = var_data | 49 | let expected_ty = var_data |
51 | .as_ref() | 50 | .as_ref() |
52 | .and_then(|d| d.field(&Name::new_tuple_field(i))) | 51 | .and_then(|d| d.field(&Name::new_tuple_field(i))) |
53 | .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); | 52 | .map_or(self.err_ty(), |field| { |
53 | field_tys[field].clone().substitute(&Interner, &substs) | ||
54 | }); | ||
54 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 55 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
55 | self.infer_pat(subpat, &expected_ty, default_bm); | 56 | self.infer_pat(subpat, &expected_ty, default_bm); |
56 | } | 57 | } |
@@ -67,25 +68,22 @@ impl<'a> InferenceContext<'a> { | |||
67 | id: PatId, | 68 | id: PatId, |
68 | ) -> Ty { | 69 | ) -> Ty { |
69 | let (ty, def) = self.resolve_variant(path); | 70 | let (ty, def) = self.resolve_variant(path); |
70 | let var_data = def.map(|it| variant_data(self.db.upcast(), it)); | 71 | let var_data = def.map(|it| it.variant_data(self.db.upcast())); |
71 | if let Some(variant) = def { | 72 | if let Some(variant) = def { |
72 | self.write_variant_resolution(id.into(), variant); | 73 | self.write_variant_resolution(id.into(), variant); |
73 | } | 74 | } |
74 | 75 | ||
75 | self.unify(&ty, expected); | 76 | self.unify(&ty, expected); |
76 | 77 | ||
77 | let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); | 78 | let substs = |
79 | ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(&Interner)); | ||
78 | 80 | ||
79 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); | 81 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); |
80 | for subpat in subpats { | 82 | for subpat in subpats { |
81 | let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); | 83 | let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); |
82 | if let Some(local_id) = matching_field { | 84 | let expected_ty = matching_field.map_or(self.err_ty(), |field| { |
83 | let field_def = FieldId { parent: def.unwrap(), local_id }; | 85 | field_tys[field].clone().substitute(&Interner, &substs) |
84 | self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); | 86 | }); |
85 | } | ||
86 | |||
87 | let expected_ty = matching_field | ||
88 | .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); | ||
89 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 87 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
90 | self.infer_pat(subpat.pat, &expected_ty, default_bm); | 88 | self.infer_pat(subpat.pat, &expected_ty, default_bm); |
91 | } | 89 | } |
@@ -102,7 +100,7 @@ impl<'a> InferenceContext<'a> { | |||
102 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 100 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
103 | 101 | ||
104 | if is_non_ref_pat(&body, pat) { | 102 | if is_non_ref_pat(&body, pat) { |
105 | while let Some((inner, mutability)) = expected.as_reference() { | 103 | while let Some((inner, _lifetime, mutability)) = expected.as_reference() { |
106 | expected = inner; | 104 | expected = inner; |
107 | default_bm = match default_bm { | 105 | default_bm = match default_bm { |
108 | BindingMode::Move => BindingMode::Ref(mutability), | 106 | BindingMode::Move => BindingMode::Ref(mutability), |
@@ -124,7 +122,7 @@ impl<'a> InferenceContext<'a> { | |||
124 | let ty = match &body[pat] { | 122 | let ty = match &body[pat] { |
125 | &Pat::Tuple { ref args, ellipsis } => { | 123 | &Pat::Tuple { ref args, ellipsis } => { |
126 | let expectations = match expected.as_tuple() { | 124 | let expectations = match expected.as_tuple() { |
127 | Some(parameters) => &*parameters.0, | 125 | Some(parameters) => &*parameters.as_slice(&Interner), |
128 | _ => &[], | 126 | _ => &[], |
129 | }; | 127 | }; |
130 | 128 | ||
@@ -134,7 +132,8 @@ impl<'a> InferenceContext<'a> { | |||
134 | }; | 132 | }; |
135 | let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); | 133 | let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); |
136 | let err_ty = self.err_ty(); | 134 | let err_ty = self.err_ty(); |
137 | let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); | 135 | let mut expectations_iter = |
136 | expectations.iter().map(|a| a.assert_ty_ref(&Interner)).chain(repeat(&err_ty)); | ||
138 | let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); | 137 | let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); |
139 | 138 | ||
140 | let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); | 139 | let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); |
@@ -142,7 +141,8 @@ impl<'a> InferenceContext<'a> { | |||
142 | inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); | 141 | inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); |
143 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); | 142 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); |
144 | 143 | ||
145 | TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner) | 144 | TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys)) |
145 | .intern(&Interner) | ||
146 | } | 146 | } |
147 | Pat::Or(ref pats) => { | 147 | Pat::Or(ref pats) => { |
148 | if let Some((first_pat, rest)) = pats.split_first() { | 148 | if let Some((first_pat, rest)) = pats.split_first() { |
@@ -158,7 +158,7 @@ impl<'a> InferenceContext<'a> { | |||
158 | Pat::Ref { pat, mutability } => { | 158 | Pat::Ref { pat, mutability } => { |
159 | let mutability = lower_to_chalk_mutability(*mutability); | 159 | let mutability = lower_to_chalk_mutability(*mutability); |
160 | let expectation = match expected.as_reference() { | 160 | let expectation = match expected.as_reference() { |
161 | Some((inner_ty, exp_mut)) => { | 161 | Some((inner_ty, _lifetime, exp_mut)) => { |
162 | if mutability != exp_mut { | 162 | if mutability != exp_mut { |
163 | // FIXME: emit type error? | 163 | // FIXME: emit type error? |
164 | } | 164 | } |
@@ -167,10 +167,10 @@ impl<'a> InferenceContext<'a> { | |||
167 | _ => self.result.standard_types.unknown.clone(), | 167 | _ => self.result.standard_types.unknown.clone(), |
168 | }; | 168 | }; |
169 | let subty = self.infer_pat(*pat, &expectation, default_bm); | 169 | let subty = self.infer_pat(*pat, &expectation, default_bm); |
170 | TyKind::Ref(mutability, subty).intern(&Interner) | 170 | TyKind::Ref(mutability, static_lifetime(), subty).intern(&Interner) |
171 | } | 171 | } |
172 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( | 172 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( |
173 | p.as_ref(), | 173 | p.as_deref(), |
174 | subpats, | 174 | subpats, |
175 | expected, | 175 | expected, |
176 | default_bm, | 176 | default_bm, |
@@ -178,7 +178,7 @@ impl<'a> InferenceContext<'a> { | |||
178 | *ellipsis, | 178 | *ellipsis, |
179 | ), | 179 | ), |
180 | Pat::Record { path: p, args: fields, ellipsis: _ } => { | 180 | Pat::Record { path: p, args: fields, ellipsis: _ } => { |
181 | self.infer_record_pat(p.as_ref(), fields, expected, default_bm, pat) | 181 | self.infer_record_pat(p.as_deref(), fields, expected, default_bm, pat) |
182 | } | 182 | } |
183 | Pat::Path(path) => { | 183 | Pat::Path(path) => { |
184 | // FIXME use correct resolver for the surrounding expression | 184 | // FIXME use correct resolver for the surrounding expression |
@@ -200,7 +200,8 @@ impl<'a> InferenceContext<'a> { | |||
200 | 200 | ||
201 | let bound_ty = match mode { | 201 | let bound_ty = match mode { |
202 | BindingMode::Ref(mutability) => { | 202 | BindingMode::Ref(mutability) => { |
203 | TyKind::Ref(mutability, inner_ty.clone()).intern(&Interner) | 203 | TyKind::Ref(mutability, static_lifetime(), inner_ty.clone()) |
204 | .intern(&Interner) | ||
204 | } | 205 | } |
205 | BindingMode::Move => inner_ty.clone(), | 206 | BindingMode::Move => inner_ty.clone(), |
206 | }; | 207 | }; |
@@ -209,17 +210,20 @@ impl<'a> InferenceContext<'a> { | |||
209 | return inner_ty; | 210 | return inner_ty; |
210 | } | 211 | } |
211 | Pat::Slice { prefix, slice, suffix } => { | 212 | Pat::Slice { prefix, slice, suffix } => { |
212 | let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { | 213 | let elem_ty = match expected.kind(&Interner) { |
213 | TyKind::Array(st) => (TyKind::Array, st.clone()), | 214 | TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(), |
214 | TyKind::Slice(st) => (TyKind::Slice, st.clone()), | 215 | _ => self.err_ty(), |
215 | _ => (TyKind::Slice, self.err_ty()), | ||
216 | }; | 216 | }; |
217 | 217 | ||
218 | for pat_id in prefix.iter().chain(suffix) { | 218 | for pat_id in prefix.iter().chain(suffix) { |
219 | self.infer_pat(*pat_id, &elem_ty, default_bm); | 219 | self.infer_pat(*pat_id, &elem_ty, default_bm); |
220 | } | 220 | } |
221 | 221 | ||
222 | let pat_ty = container_ty(elem_ty).intern(&Interner); | 222 | let pat_ty = match expected.kind(&Interner) { |
223 | TyKind::Array(_, const_) => TyKind::Array(elem_ty, const_.clone()), | ||
224 | _ => TyKind::Slice(elem_ty), | ||
225 | } | ||
226 | .intern(&Interner); | ||
223 | if let Some(slice_pat_id) = slice { | 227 | if let Some(slice_pat_id) = slice { |
224 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); | 228 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); |
225 | } | 229 | } |
@@ -236,30 +240,20 @@ impl<'a> InferenceContext<'a> { | |||
236 | Pat::Box { inner } => match self.resolve_boxed_box() { | 240 | Pat::Box { inner } => match self.resolve_boxed_box() { |
237 | Some(box_adt) => { | 241 | Some(box_adt) => { |
238 | let (inner_ty, alloc_ty) = match expected.as_adt() { | 242 | let (inner_ty, alloc_ty) = match expected.as_adt() { |
239 | Some((adt, subst)) if adt == box_adt => { | 243 | Some((adt, subst)) if adt == box_adt => ( |
240 | (subst[0].clone(), subst.get(1).cloned()) | 244 | subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(), |
241 | } | 245 | subst.as_slice(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()), |
246 | ), | ||
242 | _ => (self.result.standard_types.unknown.clone(), None), | 247 | _ => (self.result.standard_types.unknown.clone(), None), |
243 | }; | 248 | }; |
244 | 249 | ||
245 | let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm); | 250 | let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm); |
246 | let mut sb = Substitution::build_for_generics(&generics( | 251 | let mut b = TyBuilder::adt(self.db, box_adt).push(inner_ty); |
247 | self.db.upcast(), | 252 | |
248 | box_adt.into(), | 253 | if let Some(alloc_ty) = alloc_ty { |
249 | )); | 254 | b = b.push(alloc_ty); |
250 | sb = sb.push(inner_ty); | ||
251 | if sb.remaining() == 1 { | ||
252 | sb = sb.push(match alloc_ty { | ||
253 | Some(alloc_ty) if !alloc_ty.is_unknown() => alloc_ty, | ||
254 | _ => match self.db.generic_defaults(box_adt.into()).get(1) { | ||
255 | Some(alloc_ty) if !alloc_ty.value.is_unknown() => { | ||
256 | alloc_ty.value.clone() | ||
257 | } | ||
258 | _ => self.table.new_type_var(), | ||
259 | }, | ||
260 | }); | ||
261 | } | 255 | } |
262 | Ty::adt_ty(box_adt, sb.build()) | 256 | b.fill_with_defaults(self.db, || self.table.new_type_var()).build() |
263 | } | 257 | } |
264 | None => self.err_ty(), | 258 | None => self.err_ty(), |
265 | }, | 259 | }, |
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index cefa38509..495282eba 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs | |||
@@ -11,7 +11,8 @@ use hir_def::{ | |||
11 | use hir_expand::name::Name; | 11 | use hir_expand::name::Name; |
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId, | 14 | method_resolution, Interner, Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, |
15 | ValueTyDefId, | ||
15 | }; | 16 | }; |
16 | 17 | ||
17 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | 18 | use super::{ExprOrPatId, InferenceContext, TraitRef}; |
@@ -82,10 +83,10 @@ impl<'a> InferenceContext<'a> { | |||
82 | } | 83 | } |
83 | ValueNs::ImplSelf(impl_id) => { | 84 | ValueNs::ImplSelf(impl_id) => { |
84 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); | 85 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); |
85 | let substs = Substitution::type_params_for_generics(self.db, &generics); | 86 | let substs = generics.type_params_subst(self.db); |
86 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); | 87 | let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs); |
87 | if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { | 88 | if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { |
88 | let ty = self.db.value_ty(struct_id.into()).subst(&substs); | 89 | let ty = self.db.value_ty(struct_id.into()).substitute(&Interner, &substs); |
89 | return Some(ty); | 90 | return Some(ty); |
90 | } else { | 91 | } else { |
91 | // FIXME: diagnostic, invalid Self reference | 92 | // FIXME: diagnostic, invalid Self reference |
@@ -95,16 +96,13 @@ impl<'a> InferenceContext<'a> { | |||
95 | ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), | 96 | ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), |
96 | }; | 97 | }; |
97 | 98 | ||
98 | let ty = self.db.value_ty(typable); | 99 | let parent_substs = self_subst.unwrap_or_else(|| Substitution::empty(&Interner)); |
99 | // self_subst is just for the parent | ||
100 | let parent_substs = self_subst.unwrap_or_else(Substitution::empty); | ||
101 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); | 100 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); |
102 | let substs = ctx.substs_from_path(path, typable, true); | 101 | let substs = ctx.substs_from_path(path, typable, true); |
103 | let full_substs = Substitution::builder(substs.len()) | 102 | let ty = TyBuilder::value_ty(self.db, typable) |
104 | .use_parent_substs(&parent_substs) | 103 | .use_parent_substs(&parent_substs) |
105 | .fill(substs.0[parent_substs.len()..].iter().cloned()) | 104 | .fill(substs.as_slice(&Interner)[parent_substs.len(&Interner)..].iter().cloned()) |
106 | .build(); | 105 | .build(); |
107 | let ty = ty.subst(&full_substs); | ||
108 | Some(ty) | 106 | Some(ty) |
109 | } | 107 | } |
110 | 108 | ||
@@ -147,7 +145,7 @@ impl<'a> InferenceContext<'a> { | |||
147 | remaining_segments_for_ty, | 145 | remaining_segments_for_ty, |
148 | true, | 146 | true, |
149 | ); | 147 | ); |
150 | if let TyKind::Unknown = ty.interned(&Interner) { | 148 | if let TyKind::Error = ty.kind(&Interner) { |
151 | return None; | 149 | return None; |
152 | } | 150 | } |
153 | 151 | ||
@@ -212,7 +210,7 @@ impl<'a> InferenceContext<'a> { | |||
212 | name: &Name, | 210 | name: &Name, |
213 | id: ExprOrPatId, | 211 | id: ExprOrPatId, |
214 | ) -> Option<(ValueNs, Option<Substitution>)> { | 212 | ) -> Option<(ValueNs, Option<Substitution>)> { |
215 | if let TyKind::Unknown = ty.interned(&Interner) { | 213 | if let TyKind::Error = ty.kind(&Interner) { |
216 | return None; | 214 | return None; |
217 | } | 215 | } |
218 | 216 | ||
@@ -245,27 +243,22 @@ impl<'a> InferenceContext<'a> { | |||
245 | }; | 243 | }; |
246 | let substs = match container { | 244 | let substs = match container { |
247 | AssocContainerId::ImplId(impl_id) => { | 245 | AssocContainerId::ImplId(impl_id) => { |
248 | let impl_substs = Substitution::build_for_def(self.db, impl_id) | 246 | let impl_substs = TyBuilder::subst_for_def(self.db, impl_id) |
249 | .fill(iter::repeat_with(|| self.table.new_type_var())) | 247 | .fill(iter::repeat_with(|| self.table.new_type_var())) |
250 | .build(); | 248 | .build(); |
251 | let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); | 249 | let impl_self_ty = |
250 | self.db.impl_self_ty(impl_id).substitute(&Interner, &impl_substs); | ||
252 | self.unify(&impl_self_ty, &ty); | 251 | self.unify(&impl_self_ty, &ty); |
253 | Some(impl_substs) | 252 | Some(impl_substs) |
254 | } | 253 | } |
255 | AssocContainerId::TraitId(trait_) => { | 254 | AssocContainerId::TraitId(trait_) => { |
256 | // we're picking this method | 255 | // we're picking this method |
257 | let trait_substs = Substitution::build_for_def(self.db, trait_) | 256 | let trait_ref = TyBuilder::trait_ref(self.db, trait_) |
258 | .push(ty.clone()) | 257 | .push(ty.clone()) |
259 | .fill(std::iter::repeat_with(|| self.table.new_type_var())) | 258 | .fill(std::iter::repeat_with(|| self.table.new_type_var())) |
260 | .build(); | 259 | .build(); |
261 | self.obligations.push( | 260 | self.push_obligation(trait_ref.clone().cast(&Interner)); |
262 | TraitRef { | 261 | Some(trait_ref.substitution) |
263 | trait_id: to_chalk_trait_id(trait_), | ||
264 | substitution: trait_substs.clone(), | ||
265 | } | ||
266 | .cast(&Interner), | ||
267 | ); | ||
268 | Some(trait_substs) | ||
269 | } | 262 | } |
270 | AssocContainerId::ModuleId(_) => None, | 263 | AssocContainerId::ModuleId(_) => None, |
271 | }; | 264 | }; |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 6e7b0f5a6..a887e20b0 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -2,13 +2,17 @@ | |||
2 | 2 | ||
3 | use std::borrow::Cow; | 3 | use std::borrow::Cow; |
4 | 4 | ||
5 | use chalk_ir::{FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind}; | 5 | use chalk_ir::{ |
6 | cast::Cast, fold::Fold, interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, | ||
7 | VariableKind, | ||
8 | }; | ||
6 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | 9 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; |
7 | 10 | ||
8 | use super::{DomainGoal, InferenceContext}; | 11 | use super::{DomainGoal, InferenceContext}; |
9 | use crate::{ | 12 | use crate::{ |
10 | AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, | 13 | fold_tys, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, |
11 | InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, | 14 | DebruijnIndex, FnPointer, FnSubst, InEnvironment, InferenceVar, Interner, Scalar, Substitution, |
15 | Ty, TyExt, TyKind, WhereClause, | ||
12 | }; | 16 | }; |
13 | 17 | ||
14 | impl<'a> InferenceContext<'a> { | 18 | impl<'a> InferenceContext<'a> { |
@@ -33,7 +37,10 @@ where | |||
33 | } | 37 | } |
34 | 38 | ||
35 | #[derive(Debug)] | 39 | #[derive(Debug)] |
36 | pub(super) struct Canonicalized<T> { | 40 | pub(super) struct Canonicalized<T> |
41 | where | ||
42 | T: HasInterner<Interner = Interner>, | ||
43 | { | ||
37 | pub(super) value: Canonical<T>, | 44 | pub(super) value: Canonical<T>, |
38 | free_vars: Vec<(InferenceVar, TyVariableKind)>, | 45 | free_vars: Vec<(InferenceVar, TyVariableKind)>, |
39 | } | 46 | } |
@@ -47,11 +54,16 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
47 | }) | 54 | }) |
48 | } | 55 | } |
49 | 56 | ||
50 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { | 57 | fn do_canonicalize<T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>>( |
51 | t.fold_binders( | 58 | &mut self, |
52 | &mut |ty, binders| match ty.interned(&Interner) { | 59 | t: T, |
60 | binders: DebruijnIndex, | ||
61 | ) -> T { | ||
62 | fold_tys( | ||
63 | t, | ||
64 | |ty, binders| match ty.kind(&Interner) { | ||
53 | &TyKind::InferenceVar(var, kind) => { | 65 | &TyKind::InferenceVar(var, kind) => { |
54 | let inner = var.to_inner(); | 66 | let inner = from_inference_var(var); |
55 | if self.var_stack.contains(&inner) { | 67 | if self.var_stack.contains(&inner) { |
56 | // recursive type | 68 | // recursive type |
57 | return self.ctx.table.type_variable_table.fallback_value(var, kind); | 69 | return self.ctx.table.type_variable_table.fallback_value(var, kind); |
@@ -65,7 +77,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
65 | result | 77 | result |
66 | } else { | 78 | } else { |
67 | let root = self.ctx.table.var_unification_table.find(inner); | 79 | let root = self.ctx.table.var_unification_table.find(inner); |
68 | let position = self.add(InferenceVar::from_inner(root), kind); | 80 | let position = self.add(to_inference_var(root), kind); |
69 | TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner) | 81 | TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner) |
70 | } | 82 | } |
71 | } | 83 | } |
@@ -75,7 +87,10 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
75 | ) | 87 | ) |
76 | } | 88 | } |
77 | 89 | ||
78 | fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { | 90 | fn into_canonicalized<T: HasInterner<Interner = Interner>>( |
91 | self, | ||
92 | result: T, | ||
93 | ) -> Canonicalized<T> { | ||
79 | let kinds = self | 94 | let kinds = self |
80 | .free_vars | 95 | .free_vars |
81 | .iter() | 96 | .iter() |
@@ -102,25 +117,18 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
102 | DomainGoal::Holds(wc) => { | 117 | DomainGoal::Holds(wc) => { |
103 | DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST)) | 118 | DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST)) |
104 | } | 119 | } |
120 | _ => unimplemented!(), | ||
105 | }; | 121 | }; |
106 | self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment }) | 122 | self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment }) |
107 | } | 123 | } |
108 | } | 124 | } |
109 | 125 | ||
110 | impl<T> Canonicalized<T> { | 126 | impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { |
111 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { | 127 | pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { |
112 | ty.walk_mut_binders( | 128 | crate::fold_free_vars(ty, |bound, _binders| { |
113 | &mut |ty, binders| { | 129 | let (v, k) = self.free_vars[bound.index]; |
114 | if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { | 130 | TyKind::InferenceVar(v, k).intern(&Interner) |
115 | if bound.debruijn >= binders { | 131 | }) |
116 | let (v, k) = self.free_vars[bound.index]; | ||
117 | *ty = TyKind::InferenceVar(v, k).intern(&Interner); | ||
118 | } | ||
119 | } | ||
120 | }, | ||
121 | DebruijnIndex::INNERMOST, | ||
122 | ); | ||
123 | ty | ||
124 | } | 132 | } |
125 | 133 | ||
126 | pub(super) fn apply_solution( | 134 | pub(super) fn apply_solution( |
@@ -129,29 +137,30 @@ impl<T> Canonicalized<T> { | |||
129 | solution: Canonical<Substitution>, | 137 | solution: Canonical<Substitution>, |
130 | ) { | 138 | ) { |
131 | // the solution may contain new variables, which we need to convert to new inference vars | 139 | // the solution may contain new variables, which we need to convert to new inference vars |
132 | let new_vars = Substitution( | 140 | let new_vars = Substitution::from_iter( |
133 | solution | 141 | &Interner, |
134 | .binders | 142 | solution.binders.iter(&Interner).map(|k| match k.kind { |
135 | .iter(&Interner) | 143 | VariableKind::Ty(TyVariableKind::General) => { |
136 | .map(|k| match k.kind { | 144 | ctx.table.new_type_var().cast(&Interner) |
137 | VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), | 145 | } |
138 | VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), | 146 | VariableKind::Ty(TyVariableKind::Integer) => { |
139 | VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), | 147 | ctx.table.new_integer_var().cast(&Interner) |
140 | // HACK: Chalk can sometimes return new lifetime variables. We | 148 | } |
141 | // want to just skip them, but to not mess up the indices of | 149 | VariableKind::Ty(TyVariableKind::Float) => { |
142 | // other variables, we'll just create a new type variable in | 150 | ctx.table.new_float_var().cast(&Interner) |
143 | // their place instead. This should not matter (we never see the | 151 | } |
144 | // actual *uses* of the lifetime variable). | 152 | // Chalk can sometimes return new lifetime variables. We just use the static lifetime everywhere |
145 | VariableKind::Lifetime => ctx.table.new_type_var(), | 153 | VariableKind::Lifetime => static_lifetime().cast(&Interner), |
146 | _ => panic!("const variable in solution"), | 154 | _ => panic!("const variable in solution"), |
147 | }) | 155 | }), |
148 | .collect(), | ||
149 | ); | 156 | ); |
150 | for (i, ty) in solution.value.into_iter().enumerate() { | 157 | for (i, ty) in solution.value.iter(&Interner).enumerate() { |
151 | let (v, k) = self.free_vars[i]; | 158 | let (v, k) = self.free_vars[i]; |
152 | // eagerly replace projections in the type; we may be getting types | 159 | // eagerly replace projections in the type; we may be getting types |
153 | // e.g. from where clauses where this hasn't happened yet | 160 | // e.g. from where clauses where this hasn't happened yet |
154 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); | 161 | let ty = ctx.normalize_associated_types_in( |
162 | new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner), | ||
163 | ); | ||
155 | ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); | 164 | ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); |
156 | } | 165 | } |
157 | } | 166 | } |
@@ -163,22 +172,23 @@ pub fn could_unify(t1: &Ty, t2: &Ty) -> bool { | |||
163 | 172 | ||
164 | pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { | 173 | pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { |
165 | let mut table = InferenceTable::new(); | 174 | let mut table = InferenceTable::new(); |
166 | let vars = Substitution( | 175 | let vars = Substitution::from_iter( |
176 | &Interner, | ||
167 | tys.binders | 177 | tys.binders |
168 | .iter(&Interner) | 178 | .iter(&Interner) |
169 | // we always use type vars here because we want everything to | 179 | // we always use type vars here because we want everything to |
170 | // fallback to Unknown in the end (kind of hacky, as below) | 180 | // fallback to Unknown in the end (kind of hacky, as below) |
171 | .map(|_| table.new_type_var()) | 181 | .map(|_| table.new_type_var()), |
172 | .collect(), | ||
173 | ); | 182 | ); |
174 | let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); | 183 | let ty1_with_vars = vars.apply(tys.value.0.clone(), &Interner); |
175 | let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); | 184 | let ty2_with_vars = vars.apply(tys.value.1.clone(), &Interner); |
176 | if !table.unify(&ty1_with_vars, &ty2_with_vars) { | 185 | if !table.unify(&ty1_with_vars, &ty2_with_vars) { |
177 | return None; | 186 | return None; |
178 | } | 187 | } |
179 | // default any type vars that weren't unified back to their original bound vars | 188 | // default any type vars that weren't unified back to their original bound vars |
180 | // (kind of hacky) | 189 | // (kind of hacky) |
181 | for (i, var) in vars.iter().enumerate() { | 190 | for (i, var) in vars.iter(&Interner).enumerate() { |
191 | let var = var.assert_ty_ref(&Interner); | ||
182 | if &*table.resolve_ty_shallow(var) == var { | 192 | if &*table.resolve_ty_shallow(var) == var { |
183 | table.unify( | 193 | table.unify( |
184 | var, | 194 | var, |
@@ -186,11 +196,11 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { | |||
186 | ); | 196 | ); |
187 | } | 197 | } |
188 | } | 198 | } |
189 | Some( | 199 | Some(Substitution::from_iter( |
190 | Substitution::builder(tys.binders.len(&Interner)) | 200 | &Interner, |
191 | .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) | 201 | vars.iter(&Interner) |
192 | .build(), | 202 | .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())), |
193 | ) | 203 | )) |
194 | } | 204 | } |
195 | 205 | ||
196 | #[derive(Clone, Debug)] | 206 | #[derive(Clone, Debug)] |
@@ -204,17 +214,17 @@ impl TypeVariableTable { | |||
204 | } | 214 | } |
205 | 215 | ||
206 | pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { | 216 | pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { |
207 | self.inner[iv.to_inner().0 as usize].diverging = diverging; | 217 | self.inner[from_inference_var(iv).0 as usize].diverging = diverging; |
208 | } | 218 | } |
209 | 219 | ||
210 | fn is_diverging(&mut self, iv: InferenceVar) -> bool { | 220 | fn is_diverging(&mut self, iv: InferenceVar) -> bool { |
211 | self.inner[iv.to_inner().0 as usize].diverging | 221 | self.inner[from_inference_var(iv).0 as usize].diverging |
212 | } | 222 | } |
213 | 223 | ||
214 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { | 224 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { |
215 | match kind { | 225 | match kind { |
216 | _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never, | 226 | _ if self.inner[from_inference_var(iv).0 as usize].diverging => TyKind::Never, |
217 | TyVariableKind::General => TyKind::Unknown, | 227 | TyVariableKind::General => TyKind::Error, |
218 | TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), | 228 | TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), |
219 | TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), | 229 | TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), |
220 | } | 230 | } |
@@ -231,6 +241,7 @@ pub(crate) struct TypeVariableData { | |||
231 | pub(crate) struct InferenceTable { | 241 | pub(crate) struct InferenceTable { |
232 | pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, | 242 | pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, |
233 | pub(super) type_variable_table: TypeVariableTable, | 243 | pub(super) type_variable_table: TypeVariableTable, |
244 | pub(super) revision: u32, | ||
234 | } | 245 | } |
235 | 246 | ||
236 | impl InferenceTable { | 247 | impl InferenceTable { |
@@ -238,6 +249,7 @@ impl InferenceTable { | |||
238 | InferenceTable { | 249 | InferenceTable { |
239 | var_unification_table: InPlaceUnificationTable::new(), | 250 | var_unification_table: InPlaceUnificationTable::new(), |
240 | type_variable_table: TypeVariableTable { inner: Vec::new() }, | 251 | type_variable_table: TypeVariableTable { inner: Vec::new() }, |
252 | revision: 0, | ||
241 | } | 253 | } |
242 | } | 254 | } |
243 | 255 | ||
@@ -245,7 +257,7 @@ impl InferenceTable { | |||
245 | self.type_variable_table.push(TypeVariableData { diverging }); | 257 | self.type_variable_table.push(TypeVariableData { diverging }); |
246 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); | 258 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); |
247 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); | 259 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); |
248 | TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) | 260 | TyKind::InferenceVar(to_inference_var(key), kind).intern(&Interner) |
249 | } | 261 | } |
250 | 262 | ||
251 | pub(crate) fn new_type_var(&mut self) -> Ty { | 263 | pub(crate) fn new_type_var(&mut self) -> Ty { |
@@ -282,7 +294,9 @@ impl InferenceTable { | |||
282 | substs2: &Substitution, | 294 | substs2: &Substitution, |
283 | depth: usize, | 295 | depth: usize, |
284 | ) -> bool { | 296 | ) -> bool { |
285 | substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) | 297 | substs1.iter(&Interner).zip(substs2.iter(&Interner)).all(|(t1, t2)| { |
298 | self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth) | ||
299 | }) | ||
286 | } | 300 | } |
287 | 301 | ||
288 | fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { | 302 | fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { |
@@ -297,12 +311,12 @@ impl InferenceTable { | |||
297 | let ty1 = self.resolve_ty_shallow(ty1); | 311 | let ty1 = self.resolve_ty_shallow(ty1); |
298 | let ty2 = self.resolve_ty_shallow(ty2); | 312 | let ty2 = self.resolve_ty_shallow(ty2); |
299 | if ty1.equals_ctor(&ty2) { | 313 | if ty1.equals_ctor(&ty2) { |
300 | match (ty1.interned(&Interner), ty2.interned(&Interner)) { | 314 | match (ty1.kind(&Interner), ty2.kind(&Interner)) { |
301 | (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) | 315 | (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) |
302 | | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) | 316 | | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) |
303 | | ( | 317 | | ( |
304 | TyKind::Function(FnPointer { substs: substs1, .. }), | 318 | TyKind::Function(FnPointer { substitution: FnSubst(substs1), .. }), |
305 | TyKind::Function(FnPointer { substs: substs2, .. }), | 319 | TyKind::Function(FnPointer { substitution: FnSubst(substs2), .. }), |
306 | ) | 320 | ) |
307 | | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) | 321 | | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) |
308 | | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) | 322 | | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) |
@@ -310,9 +324,11 @@ impl InferenceTable { | |||
310 | | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { | 324 | | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { |
311 | self.unify_substs(substs1, substs2, depth + 1) | 325 | self.unify_substs(substs1, substs2, depth + 1) |
312 | } | 326 | } |
313 | (TyKind::Ref(_, ty1), TyKind::Ref(_, ty2)) | 327 | (TyKind::Array(ty1, c1), TyKind::Array(ty2, c2)) if c1 == c2 => { |
328 | self.unify_inner(ty1, ty2, depth + 1) | ||
329 | } | ||
330 | (TyKind::Ref(_, _, ty1), TyKind::Ref(_, _, ty2)) | ||
314 | | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) | 331 | | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) |
315 | | (TyKind::Array(ty1), TyKind::Array(ty2)) | ||
316 | | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), | 332 | | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), |
317 | _ => true, /* we checked equals_ctor already */ | 333 | _ => true, /* we checked equals_ctor already */ |
318 | } | 334 | } |
@@ -322,8 +338,8 @@ impl InferenceTable { | |||
322 | } | 338 | } |
323 | 339 | ||
324 | pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { | 340 | pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { |
325 | match (ty1.interned(&Interner), ty2.interned(&Interner)) { | 341 | match (ty1.kind(&Interner), ty2.kind(&Interner)) { |
326 | (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, | 342 | (TyKind::Error, _) | (_, TyKind::Error) => true, |
327 | 343 | ||
328 | (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, | 344 | (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, |
329 | 345 | ||
@@ -360,7 +376,14 @@ impl InferenceTable { | |||
360 | == self.type_variable_table.is_diverging(*tv2) => | 376 | == self.type_variable_table.is_diverging(*tv2) => |
361 | { | 377 | { |
362 | // both type vars are unknown since we tried to resolve them | 378 | // both type vars are unknown since we tried to resolve them |
363 | self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); | 379 | if !self |
380 | .var_unification_table | ||
381 | .unioned(from_inference_var(*tv1), from_inference_var(*tv2)) | ||
382 | { | ||
383 | self.var_unification_table | ||
384 | .union(from_inference_var(*tv1), from_inference_var(*tv2)); | ||
385 | self.revision += 1; | ||
386 | } | ||
364 | true | 387 | true |
365 | } | 388 | } |
366 | 389 | ||
@@ -395,9 +418,10 @@ impl InferenceTable { | |||
395 | ) => { | 418 | ) => { |
396 | // the type var is unknown since we tried to resolve it | 419 | // the type var is unknown since we tried to resolve it |
397 | self.var_unification_table.union_value( | 420 | self.var_unification_table.union_value( |
398 | tv.to_inner(), | 421 | from_inference_var(*tv), |
399 | TypeVarValue::Known(other.clone().intern(&Interner)), | 422 | TypeVarValue::Known(other.clone().intern(&Interner)), |
400 | ); | 423 | ); |
424 | self.revision += 1; | ||
401 | true | 425 | true |
402 | } | 426 | } |
403 | 427 | ||
@@ -447,9 +471,9 @@ impl InferenceTable { | |||
447 | if i > 0 { | 471 | if i > 0 { |
448 | cov_mark::hit!(type_var_resolves_to_int_var); | 472 | cov_mark::hit!(type_var_resolves_to_int_var); |
449 | } | 473 | } |
450 | match ty.interned(&Interner) { | 474 | match ty.kind(&Interner) { |
451 | TyKind::InferenceVar(tv, _) => { | 475 | TyKind::InferenceVar(tv, _) => { |
452 | let inner = tv.to_inner(); | 476 | let inner = from_inference_var(*tv); |
453 | match self.var_unification_table.inlined_probe_value(inner).known() { | 477 | match self.var_unification_table.inlined_probe_value(inner).known() { |
454 | Some(known_ty) => { | 478 | Some(known_ty) => { |
455 | // The known_ty can't be a type var itself | 479 | // The known_ty can't be a type var itself |
@@ -470,55 +494,63 @@ impl InferenceTable { | |||
470 | /// be resolved as far as possible, i.e. contain no type variables with | 494 | /// be resolved as far as possible, i.e. contain no type variables with |
471 | /// known type. | 495 | /// known type. |
472 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 496 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
473 | ty.fold(&mut |ty| match ty.interned(&Interner) { | 497 | fold_tys( |
474 | &TyKind::InferenceVar(tv, kind) => { | 498 | ty, |
475 | let inner = tv.to_inner(); | 499 | |ty, _| match ty.kind(&Interner) { |
476 | if tv_stack.contains(&inner) { | 500 | &TyKind::InferenceVar(tv, kind) => { |
477 | cov_mark::hit!(type_var_cycles_resolve_as_possible); | 501 | let inner = from_inference_var(tv); |
478 | // recursive type | 502 | if tv_stack.contains(&inner) { |
479 | return self.type_variable_table.fallback_value(tv, kind); | 503 | cov_mark::hit!(type_var_cycles_resolve_as_possible); |
480 | } | 504 | // recursive type |
481 | if let Some(known_ty) = | 505 | return self.type_variable_table.fallback_value(tv, kind); |
482 | self.var_unification_table.inlined_probe_value(inner).known() | 506 | } |
483 | { | 507 | if let Some(known_ty) = |
484 | // known_ty may contain other variables that are known by now | 508 | self.var_unification_table.inlined_probe_value(inner).known() |
485 | tv_stack.push(inner); | 509 | { |
486 | let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone()); | 510 | // known_ty may contain other variables that are known by now |
487 | tv_stack.pop(); | 511 | tv_stack.push(inner); |
488 | result | 512 | let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone()); |
489 | } else { | 513 | tv_stack.pop(); |
490 | ty | 514 | result |
515 | } else { | ||
516 | ty | ||
517 | } | ||
491 | } | 518 | } |
492 | } | 519 | _ => ty, |
493 | _ => ty, | 520 | }, |
494 | }) | 521 | DebruijnIndex::INNERMOST, |
522 | ) | ||
495 | } | 523 | } |
496 | 524 | ||
497 | /// Resolves the type completely; type variables without known type are | 525 | /// Resolves the type completely; type variables without known type are |
498 | /// replaced by TyKind::Unknown. | 526 | /// replaced by TyKind::Unknown. |
499 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 527 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
500 | ty.fold(&mut |ty| match ty.interned(&Interner) { | 528 | fold_tys( |
501 | &TyKind::InferenceVar(tv, kind) => { | 529 | ty, |
502 | let inner = tv.to_inner(); | 530 | |ty, _| match ty.kind(&Interner) { |
503 | if tv_stack.contains(&inner) { | 531 | &TyKind::InferenceVar(tv, kind) => { |
504 | cov_mark::hit!(type_var_cycles_resolve_completely); | 532 | let inner = from_inference_var(tv); |
505 | // recursive type | 533 | if tv_stack.contains(&inner) { |
506 | return self.type_variable_table.fallback_value(tv, kind); | 534 | cov_mark::hit!(type_var_cycles_resolve_completely); |
507 | } | 535 | // recursive type |
508 | if let Some(known_ty) = | 536 | return self.type_variable_table.fallback_value(tv, kind); |
509 | self.var_unification_table.inlined_probe_value(inner).known() | 537 | } |
510 | { | 538 | if let Some(known_ty) = |
511 | // known_ty may contain other variables that are known by now | 539 | self.var_unification_table.inlined_probe_value(inner).known() |
512 | tv_stack.push(inner); | 540 | { |
513 | let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); | 541 | // known_ty may contain other variables that are known by now |
514 | tv_stack.pop(); | 542 | tv_stack.push(inner); |
515 | result | 543 | let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); |
516 | } else { | 544 | tv_stack.pop(); |
517 | self.type_variable_table.fallback_value(tv, kind) | 545 | result |
546 | } else { | ||
547 | self.type_variable_table.fallback_value(tv, kind) | ||
548 | } | ||
518 | } | 549 | } |
519 | } | 550 | _ => ty, |
520 | _ => ty, | 551 | }, |
521 | }) | 552 | DebruijnIndex::INNERMOST, |
553 | ) | ||
522 | } | 554 | } |
523 | } | 555 | } |
524 | 556 | ||
@@ -542,6 +574,14 @@ impl UnifyKey for TypeVarId { | |||
542 | } | 574 | } |
543 | } | 575 | } |
544 | 576 | ||
577 | fn from_inference_var(var: InferenceVar) -> TypeVarId { | ||
578 | TypeVarId(var.index()) | ||
579 | } | ||
580 | |||
581 | fn to_inference_var(TypeVarId(index): TypeVarId) -> InferenceVar { | ||
582 | index.into() | ||
583 | } | ||
584 | |||
545 | /// The value of a type variable: either we already know the type, or we don't | 585 | /// The value of a type variable: either we already know the type, or we don't |
546 | /// know it yet. | 586 | /// know it yet. |
547 | #[derive(Clone, PartialEq, Eq, Debug)] | 587 | #[derive(Clone, PartialEq, Eq, Debug)] |