diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 39 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 136 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 45 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/path.rs | 33 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 72 |
5 files changed, 147 insertions, 178 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 9c62932b1..028a4d568 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, traits::Solution, Interner, Ty, TyBuilder, 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,7 +71,7 @@ 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.interned_mut(), to_ty.kind(&Interner)) { |
77 | // `*mut T` -> `*const T` | 75 | // `*mut T` -> `*const T` |
78 | // `&mut T` -> `&T` | 76 | // `&mut T` -> `&T` |
79 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) | 77 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) |
@@ -95,12 +93,12 @@ impl<'a> InferenceContext<'a> { | |||
95 | (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { | 93 | (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { |
96 | None => return false, | 94 | None => return false, |
97 | Some(sig) => { | 95 | Some(sig) => { |
98 | from_ty = Ty::fn_ptr(sig); | 96 | from_ty = TyBuilder::fn_ptr(sig); |
99 | } | 97 | } |
100 | }, | 98 | }, |
101 | 99 | ||
102 | (TyKind::Closure(.., substs), TyKind::Function { .. }) => { | 100 | (TyKind::Closure(.., substs), TyKind::Function { .. }) => { |
103 | from_ty = substs[0].clone(); | 101 | from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone(); |
104 | } | 102 | } |
105 | 103 | ||
106 | _ => {} | 104 | _ => {} |
@@ -111,7 +109,7 @@ impl<'a> InferenceContext<'a> { | |||
111 | } | 109 | } |
112 | 110 | ||
113 | // Auto Deref if cannot coerce | 111 | // Auto Deref if cannot coerce |
114 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { | 112 | match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { |
115 | // FIXME: DerefMut | 113 | // FIXME: DerefMut |
116 | (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), | 114 | (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), |
117 | 115 | ||
@@ -130,18 +128,15 @@ impl<'a> InferenceContext<'a> { | |||
130 | _ => return None, | 128 | _ => return None, |
131 | }; | 129 | }; |
132 | 130 | ||
133 | let generic_params = crate::utils::generics(self.db.upcast(), coerce_unsized_trait.into()); | 131 | let trait_ref = { |
134 | if generic_params.len() != 2 { | 132 | let b = TyBuilder::trait_ref(self.db, coerce_unsized_trait); |
135 | // The CoerceUnsized trait should have two generic params: Self and T. | 133 | if b.remaining() != 2 { |
136 | return None; | 134 | // The CoerceUnsized trait should have two generic params: Self and T. |
137 | } | 135 | return None; |
136 | } | ||
137 | b.push(from_ty.clone()).push(to_ty.clone()).build() | ||
138 | }; | ||
138 | 139 | ||
139 | let substs = Substitution::build_for_generics(&generic_params) | ||
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)); | 140 | let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner)); |
146 | 141 | ||
147 | let canonicalizer = self.canonicalizer(); | 142 | let canonicalizer = self.canonicalizer(); |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 25ab3ea4c..c584a2c08 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -19,11 +19,11 @@ use crate::{ | |||
19 | lower::lower_to_chalk_mutability, | 19 | lower::lower_to_chalk_mutability, |
20 | method_resolution, op, | 20 | method_resolution, op, |
21 | primitive::{self, UintTy}, | 21 | primitive::{self, UintTy}, |
22 | to_assoc_type_id, to_chalk_trait_id, | 22 | to_chalk_trait_id, |
23 | traits::{chalk::from_chalk, FnTrait, InEnvironment}, | 23 | traits::{chalk::from_chalk, FnTrait, InEnvironment}, |
24 | utils::{generics, variant_data, Generics}, | 24 | utils::{generics, variant_data, Generics}, |
25 | AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar, | 25 | AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Rawness, Scalar, Substitution, |
26 | Substitution, TraitRef, Ty, TyKind, | 26 | TraitRef, Ty, TyBuilder, TyKind, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | use super::{ | 29 | use super::{ |
@@ -73,38 +73,33 @@ impl<'a> InferenceContext<'a> { | |||
73 | let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; | 73 | let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; |
74 | let output_assoc_type = | 74 | let output_assoc_type = |
75 | self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; | 75 | 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 | 76 | ||
81 | let mut param_builder = Substitution::builder(num_args); | ||
82 | let mut arg_tys = vec![]; | 77 | let mut arg_tys = vec![]; |
83 | for _ in 0..num_args { | 78 | let arg_ty = TyBuilder::tuple(num_args) |
84 | let arg = self.table.new_type_var(); | 79 | .fill(repeat_with(|| { |
85 | param_builder = param_builder.push(arg.clone()); | 80 | let arg = self.table.new_type_var(); |
86 | arg_tys.push(arg); | 81 | arg_tys.push(arg.clone()); |
87 | } | 82 | arg |
88 | let parameters = param_builder.build(); | 83 | })) |
89 | let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); | 84 | .build(); |
90 | let substs = | 85 | |
91 | Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 86 | let projection = { |
87 | let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type); | ||
88 | if b.remaining() != 2 { | ||
89 | return None; | ||
90 | } | ||
91 | b.push(ty.clone()).push(arg_ty).build() | ||
92 | }; | ||
92 | 93 | ||
93 | let trait_env = self.trait_env.env.clone(); | 94 | let trait_env = self.trait_env.env.clone(); |
94 | let implements_fn_trait: DomainGoal = | 95 | let obligation = InEnvironment { |
95 | TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } | 96 | 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, | 97 | environment: trait_env, |
100 | }); | 98 | }; |
101 | if self.db.trait_solve(krate, goal.value).is_some() { | 99 | let canonical = self.canonicalizer().canonicalize_obligation(obligation.clone()); |
102 | self.push_obligation(implements_fn_trait); | 100 | if self.db.trait_solve(krate, canonical.value).is_some() { |
103 | let output_proj_ty = crate::ProjectionTy { | 101 | self.push_obligation(obligation.goal); |
104 | associated_ty_id: to_assoc_type_id(output_assoc_type), | 102 | 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)) | 103 | Some((arg_tys, return_ty)) |
109 | } else { | 104 | } else { |
110 | None | 105 | None |
@@ -138,7 +133,7 @@ impl<'a> InferenceContext<'a> { | |||
138 | both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); | 133 | both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); |
139 | let else_ty = match else_branch { | 134 | let else_ty = match else_branch { |
140 | Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), | 135 | Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), |
141 | None => Ty::unit(), | 136 | None => TyBuilder::unit(), |
142 | }; | 137 | }; |
143 | both_arms_diverge &= self.diverges; | 138 | both_arms_diverge &= self.diverges; |
144 | 139 | ||
@@ -193,7 +188,7 @@ impl<'a> InferenceContext<'a> { | |||
193 | break_ty: self.table.new_type_var(), | 188 | break_ty: self.table.new_type_var(), |
194 | label: label.map(|label| self.body[label].name.clone()), | 189 | label: label.map(|label| self.body[label].name.clone()), |
195 | }); | 190 | }); |
196 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 191 | self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit())); |
197 | 192 | ||
198 | let ctxt = self.breakables.pop().expect("breakable stack broken"); | 193 | let ctxt = self.breakables.pop().expect("breakable stack broken"); |
199 | if ctxt.may_break { | 194 | if ctxt.may_break { |
@@ -217,11 +212,11 @@ impl<'a> InferenceContext<'a> { | |||
217 | *condition, | 212 | *condition, |
218 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), | 213 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), |
219 | ); | 214 | ); |
220 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 215 | self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit())); |
221 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 216 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
222 | // the body may not run, so it diverging doesn't mean we diverge | 217 | // the body may not run, so it diverging doesn't mean we diverge |
223 | self.diverges = Diverges::Maybe; | 218 | self.diverges = Diverges::Maybe; |
224 | Ty::unit() | 219 | TyBuilder::unit() |
225 | } | 220 | } |
226 | Expr::For { iterable, body, pat, label } => { | 221 | Expr::For { iterable, body, pat, label } => { |
227 | let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 222 | let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
@@ -236,11 +231,11 @@ impl<'a> InferenceContext<'a> { | |||
236 | 231 | ||
237 | self.infer_pat(*pat, &pat_ty, BindingMode::default()); | 232 | self.infer_pat(*pat, &pat_ty, BindingMode::default()); |
238 | 233 | ||
239 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 234 | self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit())); |
240 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 235 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
241 | // the body may not run, so it diverging doesn't mean we diverge | 236 | // the body may not run, so it diverging doesn't mean we diverge |
242 | self.diverges = Diverges::Maybe; | 237 | self.diverges = Diverges::Maybe; |
243 | Ty::unit() | 238 | TyBuilder::unit() |
244 | } | 239 | } |
245 | Expr::Lambda { body, args, ret_type, arg_types } => { | 240 | Expr::Lambda { body, args, ret_type, arg_types } => { |
246 | assert_eq!(args.len(), arg_types.len()); | 241 | assert_eq!(args.len(), arg_types.len()); |
@@ -266,7 +261,7 @@ impl<'a> InferenceContext<'a> { | |||
266 | let sig_ty = TyKind::Function(FnPointer { | 261 | let sig_ty = TyKind::Function(FnPointer { |
267 | num_args: sig_tys.len() - 1, | 262 | num_args: sig_tys.len() - 1, |
268 | sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, | 263 | sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, |
269 | substs: Substitution(sig_tys.clone().into()), | 264 | substs: Substitution::from_iter(&Interner, sig_tys.clone()), |
270 | }) | 265 | }) |
271 | .intern(&Interner); | 266 | .intern(&Interner); |
272 | let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); | 267 | let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); |
@@ -360,7 +355,7 @@ impl<'a> InferenceContext<'a> { | |||
360 | let val_ty = if let Some(expr) = expr { | 355 | let val_ty = if let Some(expr) = expr { |
361 | self.infer_expr(*expr, &Expectation::none()) | 356 | self.infer_expr(*expr, &Expectation::none()) |
362 | } else { | 357 | } else { |
363 | Ty::unit() | 358 | TyBuilder::unit() |
364 | }; | 359 | }; |
365 | 360 | ||
366 | let last_ty = | 361 | let last_ty = |
@@ -386,7 +381,7 @@ impl<'a> InferenceContext<'a> { | |||
386 | if let Some(expr) = expr { | 381 | if let Some(expr) = expr { |
387 | self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); | 382 | self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); |
388 | } else { | 383 | } else { |
389 | let unit = Ty::unit(); | 384 | let unit = TyBuilder::unit(); |
390 | self.coerce(&unit, &self.return_ty.clone()); | 385 | self.coerce(&unit, &self.return_ty.clone()); |
391 | } | 386 | } |
392 | TyKind::Never.intern(&Interner) | 387 | TyKind::Never.intern(&Interner) |
@@ -406,7 +401,7 @@ impl<'a> InferenceContext<'a> { | |||
406 | 401 | ||
407 | self.unify(&ty, &expected.ty); | 402 | self.unify(&ty, &expected.ty); |
408 | 403 | ||
409 | let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); | 404 | let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner)); |
410 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); | 405 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); |
411 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); | 406 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); |
412 | for field in fields.iter() { | 407 | for field in fields.iter() { |
@@ -455,10 +450,14 @@ impl<'a> InferenceContext<'a> { | |||
455 | }) | 450 | }) |
456 | .unwrap_or(true) | 451 | .unwrap_or(true) |
457 | }; | 452 | }; |
458 | match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { | 453 | match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) { |
459 | TyKind::Tuple(_, substs) => { | 454 | TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| { |
460 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) | 455 | substs |
461 | } | 456 | .interned(&Interner) |
457 | .get(idx) | ||
458 | .map(|a| a.assert_ty_ref(&Interner)) | ||
459 | .cloned() | ||
460 | }), | ||
462 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { | 461 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { |
463 | let local_id = self.db.struct_data(*s).variant_data.field(name)?; | 462 | let local_id = self.db.struct_data(*s).variant_data.field(name)?; |
464 | let field = FieldId { parent: (*s).into(), local_id }; | 463 | let field = FieldId { parent: (*s).into(), local_id }; |
@@ -535,17 +534,10 @@ impl<'a> InferenceContext<'a> { | |||
535 | Expr::Box { expr } => { | 534 | Expr::Box { expr } => { |
536 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 535 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
537 | if let Some(box_) = self.resolve_boxed_box() { | 536 | if let Some(box_) = self.resolve_boxed_box() { |
538 | let mut sb = | 537 | TyBuilder::adt(self.db, box_) |
539 | Substitution::build_for_generics(&generics(self.db.upcast(), box_.into())); | 538 | .push(inner_ty) |
540 | sb = sb.push(inner_ty); | 539 | .fill_with_defaults(self.db, || self.table.new_type_var()) |
541 | match self.db.generic_defaults(box_.into()).get(1) { | 540 | .build() |
542 | Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => { | ||
543 | sb = sb.push(alloc_ty.value.clone()); | ||
544 | } | ||
545 | _ => (), | ||
546 | } | ||
547 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | ||
548 | Ty::adt_ty(box_, sb.build()) | ||
549 | } else { | 541 | } else { |
550 | self.err_ty() | 542 | self.err_ty() |
551 | } | 543 | } |
@@ -573,7 +565,7 @@ impl<'a> InferenceContext<'a> { | |||
573 | None => self.err_ty(), | 565 | None => self.err_ty(), |
574 | }, | 566 | }, |
575 | UnaryOp::Neg => { | 567 | UnaryOp::Neg => { |
576 | match inner_ty.interned(&Interner) { | 568 | match inner_ty.kind(&Interner) { |
577 | // Fast path for builtins | 569 | // Fast path for builtins |
578 | TyKind::Scalar(Scalar::Int(_)) | 570 | TyKind::Scalar(Scalar::Int(_)) |
579 | | TyKind::Scalar(Scalar::Uint(_)) | 571 | | TyKind::Scalar(Scalar::Uint(_)) |
@@ -586,7 +578,7 @@ impl<'a> InferenceContext<'a> { | |||
586 | } | 578 | } |
587 | } | 579 | } |
588 | UnaryOp::Not => { | 580 | UnaryOp::Not => { |
589 | match inner_ty.interned(&Interner) { | 581 | match inner_ty.kind(&Interner) { |
590 | // Fast path for builtins | 582 | // Fast path for builtins |
591 | TyKind::Scalar(Scalar::Bool) | 583 | TyKind::Scalar(Scalar::Bool) |
592 | | TyKind::Scalar(Scalar::Int(_)) | 584 | | TyKind::Scalar(Scalar::Int(_)) |
@@ -635,31 +627,31 @@ impl<'a> InferenceContext<'a> { | |||
635 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); | 627 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); |
636 | match (range_type, lhs_ty, rhs_ty) { | 628 | match (range_type, lhs_ty, rhs_ty) { |
637 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 629 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
638 | Some(adt) => Ty::adt_ty(adt, Substitution::empty()), | 630 | Some(adt) => TyBuilder::adt(self.db, adt).build(), |
639 | None => self.err_ty(), | 631 | None => self.err_ty(), |
640 | }, | 632 | }, |
641 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 633 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
642 | Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), | 634 | Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(), |
643 | None => self.err_ty(), | 635 | None => self.err_ty(), |
644 | }, | 636 | }, |
645 | (RangeOp::Inclusive, None, Some(ty)) => { | 637 | (RangeOp::Inclusive, None, Some(ty)) => { |
646 | match self.resolve_range_to_inclusive() { | 638 | match self.resolve_range_to_inclusive() { |
647 | Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), | 639 | Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(), |
648 | None => self.err_ty(), | 640 | None => self.err_ty(), |
649 | } | 641 | } |
650 | } | 642 | } |
651 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 643 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
652 | Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), | 644 | Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(), |
653 | None => self.err_ty(), | 645 | None => self.err_ty(), |
654 | }, | 646 | }, |
655 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 647 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
656 | match self.resolve_range_inclusive() { | 648 | match self.resolve_range_inclusive() { |
657 | Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), | 649 | Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(), |
658 | None => self.err_ty(), | 650 | None => self.err_ty(), |
659 | } | 651 | } |
660 | } | 652 | } |
661 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 653 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
662 | Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), | 654 | Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(), |
663 | None => self.err_ty(), | 655 | None => self.err_ty(), |
664 | }, | 656 | }, |
665 | (RangeOp::Inclusive, _, None) => self.err_ty(), | 657 | (RangeOp::Inclusive, _, None) => self.err_ty(), |
@@ -692,10 +684,10 @@ impl<'a> InferenceContext<'a> { | |||
692 | } | 684 | } |
693 | } | 685 | } |
694 | Expr::Tuple { exprs } => { | 686 | Expr::Tuple { exprs } => { |
695 | let mut tys = match expected.ty.interned(&Interner) { | 687 | let mut tys = match expected.ty.kind(&Interner) { |
696 | TyKind::Tuple(_, substs) => substs | 688 | TyKind::Tuple(_, substs) => substs |
697 | .iter() | 689 | .iter(&Interner) |
698 | .cloned() | 690 | .map(|a| a.assert_ty_ref(&Interner).clone()) |
699 | .chain(repeat_with(|| self.table.new_type_var())) | 691 | .chain(repeat_with(|| self.table.new_type_var())) |
700 | .take(exprs.len()) | 692 | .take(exprs.len()) |
701 | .collect::<Vec<_>>(), | 693 | .collect::<Vec<_>>(), |
@@ -706,10 +698,10 @@ impl<'a> InferenceContext<'a> { | |||
706 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 698 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
707 | } | 699 | } |
708 | 700 | ||
709 | TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner) | 701 | TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner) |
710 | } | 702 | } |
711 | Expr::Array(array) => { | 703 | Expr::Array(array) => { |
712 | let elem_ty = match expected.ty.interned(&Interner) { | 704 | let elem_ty = match expected.ty.kind(&Interner) { |
713 | TyKind::Array(st) | TyKind::Slice(st) => st.clone(), | 705 | TyKind::Array(st) | TyKind::Slice(st) => st.clone(), |
714 | _ => self.table.new_type_var(), | 706 | _ => self.table.new_type_var(), |
715 | }; | 707 | }; |
@@ -824,8 +816,8 @@ impl<'a> InferenceContext<'a> { | |||
824 | // we don't even make an attempt at coercion | 816 | // we don't even make an attempt at coercion |
825 | self.table.new_maybe_never_var() | 817 | self.table.new_maybe_never_var() |
826 | } else { | 818 | } else { |
827 | self.coerce(&Ty::unit(), &expected.coercion_target()); | 819 | self.coerce(&TyBuilder::unit(), &expected.coercion_target()); |
828 | Ty::unit() | 820 | TyBuilder::unit() |
829 | } | 821 | } |
830 | }; | 822 | }; |
831 | ty | 823 | ty |
@@ -953,11 +945,11 @@ impl<'a> InferenceContext<'a> { | |||
953 | substs.push(self.err_ty()); | 945 | substs.push(self.err_ty()); |
954 | } | 946 | } |
955 | assert_eq!(substs.len(), total_len); | 947 | assert_eq!(substs.len(), total_len); |
956 | Substitution(substs.into()) | 948 | Substitution::from_iter(&Interner, substs) |
957 | } | 949 | } |
958 | 950 | ||
959 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 951 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
960 | if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) { | 952 | if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) { |
961 | let def: CallableDefId = from_chalk(self.db, *fn_def); | 953 | let def: CallableDefId = from_chalk(self.db, *fn_def); |
962 | let generic_predicates = self.db.generic_predicates(def.into()); | 954 | let generic_predicates = self.db.generic_predicates(def.into()); |
963 | for predicate in generic_predicates.iter() { | 955 | for predicate in generic_predicates.iter() { |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index 474363709..5b70d5e5a 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -13,9 +13,8 @@ use hir_expand::name::Name; | |||
13 | 13 | ||
14 | use super::{BindingMode, Expectation, InferenceContext}; | 14 | use super::{BindingMode, Expectation, InferenceContext}; |
15 | use crate::{ | 15 | use crate::{ |
16 | lower::lower_to_chalk_mutability, | 16 | lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyBuilder, |
17 | utils::{generics, variant_data}, | 17 | TyKind, |
18 | Interner, Substitution, Ty, TyKind, | ||
19 | }; | 18 | }; |
20 | 19 | ||
21 | impl<'a> InferenceContext<'a> { | 20 | impl<'a> InferenceContext<'a> { |
@@ -35,7 +34,7 @@ impl<'a> InferenceContext<'a> { | |||
35 | } | 34 | } |
36 | self.unify(&ty, expected); | 35 | self.unify(&ty, expected); |
37 | 36 | ||
38 | let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); | 37 | let substs = ty.substs().cloned().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 { |
@@ -74,7 +73,7 @@ impl<'a> InferenceContext<'a> { | |||
74 | 73 | ||
75 | self.unify(&ty, expected); | 74 | self.unify(&ty, expected); |
76 | 75 | ||
77 | let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); | 76 | let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner)); |
78 | 77 | ||
79 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); | 78 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); |
80 | for subpat in subpats { | 79 | for subpat in subpats { |
@@ -134,7 +133,8 @@ impl<'a> InferenceContext<'a> { | |||
134 | }; | 133 | }; |
135 | let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); | 134 | let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); |
136 | let err_ty = self.err_ty(); | 135 | let err_ty = self.err_ty(); |
137 | let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); | 136 | let mut expectations_iter = |
137 | 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); | 138 | let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); |
139 | 139 | ||
140 | let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); | 140 | let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); |
@@ -142,7 +142,8 @@ impl<'a> InferenceContext<'a> { | |||
142 | inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); | 142 | inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); |
143 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); | 143 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); |
144 | 144 | ||
145 | TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner) | 145 | TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys)) |
146 | .intern(&Interner) | ||
146 | } | 147 | } |
147 | Pat::Or(ref pats) => { | 148 | Pat::Or(ref pats) => { |
148 | if let Some((first_pat, rest)) = pats.split_first() { | 149 | if let Some((first_pat, rest)) = pats.split_first() { |
@@ -209,7 +210,7 @@ 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 (container_ty, elem_ty): (fn(_) -> _, _) = match expected.kind(&Interner) { |
213 | TyKind::Array(st) => (TyKind::Array, st.clone()), | 214 | TyKind::Array(st) => (TyKind::Array, st.clone()), |
214 | TyKind::Slice(st) => (TyKind::Slice, st.clone()), | 215 | TyKind::Slice(st) => (TyKind::Slice, st.clone()), |
215 | _ => (TyKind::Slice, self.err_ty()), | 216 | _ => (TyKind::Slice, self.err_ty()), |
@@ -236,30 +237,20 @@ impl<'a> InferenceContext<'a> { | |||
236 | Pat::Box { inner } => match self.resolve_boxed_box() { | 237 | Pat::Box { inner } => match self.resolve_boxed_box() { |
237 | Some(box_adt) => { | 238 | Some(box_adt) => { |
238 | let (inner_ty, alloc_ty) = match expected.as_adt() { | 239 | let (inner_ty, alloc_ty) = match expected.as_adt() { |
239 | Some((adt, subst)) if adt == box_adt => { | 240 | Some((adt, subst)) if adt == box_adt => ( |
240 | (subst[0].clone(), subst.get(1).cloned()) | 241 | subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(), |
241 | } | 242 | subst.interned(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()), |
243 | ), | ||
242 | _ => (self.result.standard_types.unknown.clone(), None), | 244 | _ => (self.result.standard_types.unknown.clone(), None), |
243 | }; | 245 | }; |
244 | 246 | ||
245 | let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm); | 247 | let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm); |
246 | let mut sb = Substitution::build_for_generics(&generics( | 248 | let mut b = TyBuilder::adt(self.db, box_adt).push(inner_ty); |
247 | self.db.upcast(), | 249 | |
248 | box_adt.into(), | 250 | if let Some(alloc_ty) = alloc_ty { |
249 | )); | 251 | 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 | } | 252 | } |
262 | Ty::adt_ty(box_adt, sb.build()) | 253 | b.fill_with_defaults(self.db, || self.table.new_type_var()).build() |
263 | } | 254 | } |
264 | None => self.err_ty(), | 255 | None => self.err_ty(), |
265 | }, | 256 | }, |
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index 717738789..671ea355f 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs | |||
@@ -10,9 +10,7 @@ use hir_def::{ | |||
10 | }; | 10 | }; |
11 | use hir_expand::name::Name; | 11 | use hir_expand::name::Name; |
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{method_resolution, Interner, Substitution, Ty, TyBuilder, TyKind, ValueTyDefId}; |
14 | method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId, | ||
15 | }; | ||
16 | 14 | ||
17 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | 15 | use super::{ExprOrPatId, InferenceContext, TraitRef}; |
18 | 16 | ||
@@ -82,7 +80,7 @@ impl<'a> InferenceContext<'a> { | |||
82 | } | 80 | } |
83 | ValueNs::ImplSelf(impl_id) => { | 81 | ValueNs::ImplSelf(impl_id) => { |
84 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); | 82 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); |
85 | let substs = Substitution::type_params_for_generics(self.db, &generics); | 83 | let substs = generics.type_params_subst(self.db); |
86 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); | 84 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); |
87 | if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { | 85 | if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { |
88 | let ty = self.db.value_ty(struct_id.into()).subst(&substs); | 86 | let ty = self.db.value_ty(struct_id.into()).subst(&substs); |
@@ -95,16 +93,13 @@ impl<'a> InferenceContext<'a> { | |||
95 | ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), | 93 | ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), |
96 | }; | 94 | }; |
97 | 95 | ||
98 | let ty = self.db.value_ty(typable); | 96 | 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); | 97 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); |
102 | let substs = ctx.substs_from_path(path, typable, true); | 98 | let substs = ctx.substs_from_path(path, typable, true); |
103 | let full_substs = Substitution::builder(substs.len()) | 99 | let ty = TyBuilder::value_ty(self.db, typable) |
104 | .use_parent_substs(&parent_substs) | 100 | .use_parent_substs(&parent_substs) |
105 | .fill(substs.0[parent_substs.len()..].iter().cloned()) | 101 | .fill(substs.interned(&Interner)[parent_substs.len(&Interner)..].iter().cloned()) |
106 | .build(); | 102 | .build(); |
107 | let ty = ty.subst(&full_substs); | ||
108 | Some(ty) | 103 | Some(ty) |
109 | } | 104 | } |
110 | 105 | ||
@@ -147,7 +142,7 @@ impl<'a> InferenceContext<'a> { | |||
147 | remaining_segments_for_ty, | 142 | remaining_segments_for_ty, |
148 | true, | 143 | true, |
149 | ); | 144 | ); |
150 | if let TyKind::Unknown = ty.interned(&Interner) { | 145 | if let TyKind::Unknown = ty.kind(&Interner) { |
151 | return None; | 146 | return None; |
152 | } | 147 | } |
153 | 148 | ||
@@ -212,7 +207,7 @@ impl<'a> InferenceContext<'a> { | |||
212 | name: &Name, | 207 | name: &Name, |
213 | id: ExprOrPatId, | 208 | id: ExprOrPatId, |
214 | ) -> Option<(ValueNs, Option<Substitution>)> { | 209 | ) -> Option<(ValueNs, Option<Substitution>)> { |
215 | if let TyKind::Unknown = ty.interned(&Interner) { | 210 | if let TyKind::Unknown = ty.kind(&Interner) { |
216 | return None; | 211 | return None; |
217 | } | 212 | } |
218 | 213 | ||
@@ -245,7 +240,7 @@ impl<'a> InferenceContext<'a> { | |||
245 | }; | 240 | }; |
246 | let substs = match container { | 241 | let substs = match container { |
247 | AssocContainerId::ImplId(impl_id) => { | 242 | AssocContainerId::ImplId(impl_id) => { |
248 | let impl_substs = Substitution::build_for_def(self.db, impl_id) | 243 | let impl_substs = TyBuilder::subst_for_def(self.db, impl_id) |
249 | .fill(iter::repeat_with(|| self.table.new_type_var())) | 244 | .fill(iter::repeat_with(|| self.table.new_type_var())) |
250 | .build(); | 245 | .build(); |
251 | let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); | 246 | let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); |
@@ -254,18 +249,12 @@ impl<'a> InferenceContext<'a> { | |||
254 | } | 249 | } |
255 | AssocContainerId::TraitId(trait_) => { | 250 | AssocContainerId::TraitId(trait_) => { |
256 | // we're picking this method | 251 | // we're picking this method |
257 | let trait_substs = Substitution::build_for_def(self.db, trait_) | 252 | let trait_ref = TyBuilder::trait_ref(self.db, trait_) |
258 | .push(ty.clone()) | 253 | .push(ty.clone()) |
259 | .fill(std::iter::repeat_with(|| self.table.new_type_var())) | 254 | .fill(std::iter::repeat_with(|| self.table.new_type_var())) |
260 | .build(); | 255 | .build(); |
261 | self.push_obligation( | 256 | self.push_obligation(trait_ref.clone().cast(&Interner)); |
262 | TraitRef { | 257 | 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 | } | 258 | } |
270 | AssocContainerId::ModuleId(_) => None, | 259 | AssocContainerId::ModuleId(_) => None, |
271 | }; | 260 | }; |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 5ea4b7481..a04b935ef 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -49,7 +49,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
49 | 49 | ||
50 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { | 50 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { |
51 | t.fold_binders( | 51 | t.fold_binders( |
52 | &mut |ty, binders| match ty.interned(&Interner) { | 52 | &mut |ty, binders| match ty.kind(&Interner) { |
53 | &TyKind::InferenceVar(var, kind) => { | 53 | &TyKind::InferenceVar(var, kind) => { |
54 | let inner = var.to_inner(); | 54 | let inner = var.to_inner(); |
55 | if self.var_stack.contains(&inner) { | 55 | if self.var_stack.contains(&inner) { |
@@ -129,29 +129,28 @@ impl<T> Canonicalized<T> { | |||
129 | solution: Canonical<Substitution>, | 129 | solution: Canonical<Substitution>, |
130 | ) { | 130 | ) { |
131 | // the solution may contain new variables, which we need to convert to new inference vars | 131 | // the solution may contain new variables, which we need to convert to new inference vars |
132 | let new_vars = Substitution( | 132 | let new_vars = Substitution::from_iter( |
133 | solution | 133 | &Interner, |
134 | .binders | 134 | solution.binders.iter(&Interner).map(|k| match k.kind { |
135 | .iter(&Interner) | 135 | VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), |
136 | .map(|k| match k.kind { | 136 | VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), |
137 | VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), | 137 | VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), |
138 | VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), | 138 | // HACK: Chalk can sometimes return new lifetime variables. We |
139 | VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), | 139 | // want to just skip them, but to not mess up the indices of |
140 | // HACK: Chalk can sometimes return new lifetime variables. We | 140 | // other variables, we'll just create a new type variable in |
141 | // want to just skip them, but to not mess up the indices of | 141 | // their place instead. This should not matter (we never see the |
142 | // other variables, we'll just create a new type variable in | 142 | // actual *uses* of the lifetime variable). |
143 | // their place instead. This should not matter (we never see the | 143 | VariableKind::Lifetime => ctx.table.new_type_var(), |
144 | // actual *uses* of the lifetime variable). | 144 | _ => panic!("const variable in solution"), |
145 | VariableKind::Lifetime => ctx.table.new_type_var(), | 145 | }), |
146 | _ => panic!("const variable in solution"), | ||
147 | }) | ||
148 | .collect(), | ||
149 | ); | 146 | ); |
150 | for (i, ty) in solution.value.into_iter().enumerate() { | 147 | for (i, ty) in solution.value.iter(&Interner).enumerate() { |
151 | let (v, k) = self.free_vars[i]; | 148 | let (v, k) = self.free_vars[i]; |
152 | // eagerly replace projections in the type; we may be getting types | 149 | // eagerly replace projections in the type; we may be getting types |
153 | // e.g. from where clauses where this hasn't happened yet | 150 | // 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)); | 151 | let ty = ctx.normalize_associated_types_in( |
152 | ty.assert_ty_ref(&Interner).clone().subst_bound_vars(&new_vars), | ||
153 | ); | ||
155 | ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); | 154 | ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); |
156 | } | 155 | } |
157 | } | 156 | } |
@@ -163,13 +162,13 @@ pub fn could_unify(t1: &Ty, t2: &Ty) -> bool { | |||
163 | 162 | ||
164 | pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { | 163 | pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { |
165 | let mut table = InferenceTable::new(); | 164 | let mut table = InferenceTable::new(); |
166 | let vars = Substitution( | 165 | let vars = Substitution::from_iter( |
166 | &Interner, | ||
167 | tys.binders | 167 | tys.binders |
168 | .iter(&Interner) | 168 | .iter(&Interner) |
169 | // we always use type vars here because we want everything to | 169 | // we always use type vars here because we want everything to |
170 | // fallback to Unknown in the end (kind of hacky, as below) | 170 | // fallback to Unknown in the end (kind of hacky, as below) |
171 | .map(|_| table.new_type_var()) | 171 | .map(|_| table.new_type_var()), |
172 | .collect(), | ||
173 | ); | 172 | ); |
174 | let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); | 173 | let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); |
175 | let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); | 174 | let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); |
@@ -178,7 +177,8 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { | |||
178 | } | 177 | } |
179 | // default any type vars that weren't unified back to their original bound vars | 178 | // default any type vars that weren't unified back to their original bound vars |
180 | // (kind of hacky) | 179 | // (kind of hacky) |
181 | for (i, var) in vars.iter().enumerate() { | 180 | for (i, var) in vars.iter(&Interner).enumerate() { |
181 | let var = var.assert_ty_ref(&Interner); | ||
182 | if &*table.resolve_ty_shallow(var) == var { | 182 | if &*table.resolve_ty_shallow(var) == var { |
183 | table.unify( | 183 | table.unify( |
184 | var, | 184 | var, |
@@ -186,11 +186,11 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { | |||
186 | ); | 186 | ); |
187 | } | 187 | } |
188 | } | 188 | } |
189 | Some( | 189 | Some(Substitution::from_iter( |
190 | Substitution::builder(tys.binders.len(&Interner)) | 190 | &Interner, |
191 | .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) | 191 | vars.iter(&Interner) |
192 | .build(), | 192 | .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())), |
193 | ) | 193 | )) |
194 | } | 194 | } |
195 | 195 | ||
196 | #[derive(Clone, Debug)] | 196 | #[derive(Clone, Debug)] |
@@ -284,7 +284,9 @@ impl InferenceTable { | |||
284 | substs2: &Substitution, | 284 | substs2: &Substitution, |
285 | depth: usize, | 285 | depth: usize, |
286 | ) -> bool { | 286 | ) -> bool { |
287 | substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) | 287 | substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| { |
288 | self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth) | ||
289 | }) | ||
288 | } | 290 | } |
289 | 291 | ||
290 | fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { | 292 | fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { |
@@ -299,7 +301,7 @@ impl InferenceTable { | |||
299 | let ty1 = self.resolve_ty_shallow(ty1); | 301 | let ty1 = self.resolve_ty_shallow(ty1); |
300 | let ty2 = self.resolve_ty_shallow(ty2); | 302 | let ty2 = self.resolve_ty_shallow(ty2); |
301 | if ty1.equals_ctor(&ty2) { | 303 | if ty1.equals_ctor(&ty2) { |
302 | match (ty1.interned(&Interner), ty2.interned(&Interner)) { | 304 | match (ty1.kind(&Interner), ty2.kind(&Interner)) { |
303 | (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) | 305 | (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) |
304 | | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) | 306 | | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) |
305 | | ( | 307 | | ( |
@@ -324,7 +326,7 @@ impl InferenceTable { | |||
324 | } | 326 | } |
325 | 327 | ||
326 | pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { | 328 | pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { |
327 | match (ty1.interned(&Interner), ty2.interned(&Interner)) { | 329 | match (ty1.kind(&Interner), ty2.kind(&Interner)) { |
328 | (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, | 330 | (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, |
329 | 331 | ||
330 | (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, | 332 | (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, |
@@ -453,7 +455,7 @@ impl InferenceTable { | |||
453 | if i > 0 { | 455 | if i > 0 { |
454 | cov_mark::hit!(type_var_resolves_to_int_var); | 456 | cov_mark::hit!(type_var_resolves_to_int_var); |
455 | } | 457 | } |
456 | match ty.interned(&Interner) { | 458 | match ty.kind(&Interner) { |
457 | TyKind::InferenceVar(tv, _) => { | 459 | TyKind::InferenceVar(tv, _) => { |
458 | let inner = tv.to_inner(); | 460 | let inner = tv.to_inner(); |
459 | match self.var_unification_table.inlined_probe_value(inner).known() { | 461 | match self.var_unification_table.inlined_probe_value(inner).known() { |
@@ -476,7 +478,7 @@ impl InferenceTable { | |||
476 | /// be resolved as far as possible, i.e. contain no type variables with | 478 | /// be resolved as far as possible, i.e. contain no type variables with |
477 | /// known type. | 479 | /// known type. |
478 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 480 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
479 | ty.fold(&mut |ty| match ty.interned(&Interner) { | 481 | ty.fold(&mut |ty| match ty.kind(&Interner) { |
480 | &TyKind::InferenceVar(tv, kind) => { | 482 | &TyKind::InferenceVar(tv, kind) => { |
481 | let inner = tv.to_inner(); | 483 | let inner = tv.to_inner(); |
482 | if tv_stack.contains(&inner) { | 484 | if tv_stack.contains(&inner) { |
@@ -503,7 +505,7 @@ impl InferenceTable { | |||
503 | /// Resolves the type completely; type variables without known type are | 505 | /// Resolves the type completely; type variables without known type are |
504 | /// replaced by TyKind::Unknown. | 506 | /// replaced by TyKind::Unknown. |
505 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 507 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
506 | ty.fold(&mut |ty| match ty.interned(&Interner) { | 508 | ty.fold(&mut |ty| match ty.kind(&Interner) { |
507 | &TyKind::InferenceVar(tv, kind) => { | 509 | &TyKind::InferenceVar(tv, kind) => { |
508 | let inner = tv.to_inner(); | 510 | let inner = tv.to_inner(); |
509 | if tv_stack.contains(&inner) { | 511 | if tv_stack.contains(&inner) { |