aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer/pat.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer/pat.rs')
-rw-r--r--crates/hir_ty/src/infer/pat.rs37
1 files changed, 17 insertions, 20 deletions
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index d974f805b..a0ac8d80f 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -3,17 +3,16 @@
3use std::iter::repeat; 3use std::iter::repeat;
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use chalk_ir::Mutability;
6use hir_def::{ 7use hir_def::{
7 expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, 8 expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat},
8 path::Path, 9 path::Path,
9 type_ref::Mutability,
10 FieldId, 10 FieldId,
11}; 11};
12use hir_expand::name::Name; 12use hir_expand::name::Name;
13use test_utils::mark;
14 13
15use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
16use crate::{utils::variant_data, Substs, Ty, TypeCtor}; 15use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty};
17 16
18impl<'a> InferenceContext<'a> { 17impl<'a> InferenceContext<'a> {
19 fn infer_tuple_struct_pat( 18 fn infer_tuple_struct_pat(
@@ -32,7 +31,7 @@ impl<'a> InferenceContext<'a> {
32 } 31 }
33 self.unify(&ty, expected); 32 self.unify(&ty, expected);
34 33
35 let substs = ty.substs().unwrap_or_else(Substs::empty); 34 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
36 35
37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 36 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
38 let (pre, post) = match ellipsis { 37 let (pre, post) = match ellipsis {
@@ -71,7 +70,7 @@ impl<'a> InferenceContext<'a> {
71 70
72 self.unify(&ty, expected); 71 self.unify(&ty, expected);
73 72
74 let substs = ty.substs().unwrap_or_else(Substs::empty); 73 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
75 74
76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 75 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
77 for subpat in subpats { 76 for subpat in subpats {
@@ -103,12 +102,12 @@ impl<'a> InferenceContext<'a> {
103 expected = inner; 102 expected = inner;
104 default_bm = match default_bm { 103 default_bm = match default_bm {
105 BindingMode::Move => BindingMode::Ref(mutability), 104 BindingMode::Move => BindingMode::Ref(mutability),
106 BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared), 105 BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not),
107 BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability), 106 BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability),
108 } 107 }
109 } 108 }
110 } else if let Pat::Ref { .. } = &body[pat] { 109 } else if let Pat::Ref { .. } = &body[pat] {
111 mark::hit!(match_ergonomics_ref); 110 cov_mark::hit!(match_ergonomics_ref);
112 // When you encounter a `&pat` pattern, reset to Move. 111 // When you encounter a `&pat` pattern, reset to Move.
113 // This is so that `w` is by value: `let (_, &w) = &(1, &2);` 112 // This is so that `w` is by value: `let (_, &w) = &(1, &2);`
114 default_bm = BindingMode::Move; 113 default_bm = BindingMode::Move;
@@ -138,10 +137,7 @@ impl<'a> InferenceContext<'a> {
138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 137 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 138 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
140 139
141 Ty::apply( 140 Ty::Tuple(inner_tys.len(), Substs(inner_tys.into()))
142 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
143 Substs(inner_tys.into()),
144 )
145 } 141 }
146 Pat::Or(ref pats) => { 142 Pat::Or(ref pats) => {
147 if let Some((first_pat, rest)) = pats.split_first() { 143 if let Some((first_pat, rest)) = pats.split_first() {
@@ -155,9 +151,10 @@ impl<'a> InferenceContext<'a> {
155 } 151 }
156 } 152 }
157 Pat::Ref { pat, mutability } => { 153 Pat::Ref { pat, mutability } => {
154 let mutability = lower_to_chalk_mutability(*mutability);
158 let expectation = match expected.as_reference() { 155 let expectation = match expected.as_reference() {
159 Some((inner_ty, exp_mut)) => { 156 Some((inner_ty, exp_mut)) => {
160 if *mutability != exp_mut { 157 if mutability != exp_mut {
161 // FIXME: emit type error? 158 // FIXME: emit type error?
162 } 159 }
163 inner_ty 160 inner_ty
@@ -165,7 +162,7 @@ impl<'a> InferenceContext<'a> {
165 _ => &Ty::Unknown, 162 _ => &Ty::Unknown,
166 }; 163 };
167 let subty = self.infer_pat(*pat, expectation, default_bm); 164 let subty = self.infer_pat(*pat, expectation, default_bm);
168 Ty::apply_one(TypeCtor::Ref(*mutability), subty) 165 Ty::Ref(mutability, Substs::single(subty))
169 } 166 }
170 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 167 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
171 p.as_ref(), 168 p.as_ref(),
@@ -198,7 +195,7 @@ impl<'a> InferenceContext<'a> {
198 195
199 let bound_ty = match mode { 196 let bound_ty = match mode {
200 BindingMode::Ref(mutability) => { 197 BindingMode::Ref(mutability) => {
201 Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) 198 Ty::Ref(mutability, Substs::single(inner_ty.clone()))
202 } 199 }
203 BindingMode::Move => inner_ty.clone(), 200 BindingMode::Move => inner_ty.clone(),
204 }; 201 };
@@ -207,17 +204,17 @@ impl<'a> InferenceContext<'a> {
207 return inner_ty; 204 return inner_ty;
208 } 205 }
209 Pat::Slice { prefix, slice, suffix } => { 206 Pat::Slice { prefix, slice, suffix } => {
210 let (container_ty, elem_ty) = match &expected { 207 let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected {
211 ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), 208 Ty::Array(st) => (Ty::Array, st.as_single().clone()),
212 ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), 209 Ty::Slice(st) => (Ty::Slice, st.as_single().clone()),
213 _ => (TypeCtor::Slice, Ty::Unknown), 210 _ => (Ty::Slice, Ty::Unknown),
214 }; 211 };
215 212
216 for pat_id in prefix.iter().chain(suffix) { 213 for pat_id in prefix.iter().chain(suffix) {
217 self.infer_pat(*pat_id, &elem_ty, default_bm); 214 self.infer_pat(*pat_id, &elem_ty, default_bm);
218 } 215 }
219 216
220 let pat_ty = Ty::apply_one(container_ty, elem_ty); 217 let pat_ty = container_ty(Substs::single(elem_ty));
221 if let Some(slice_pat_id) = slice { 218 if let Some(slice_pat_id) = slice {
222 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 219 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
223 } 220 }
@@ -239,7 +236,7 @@ impl<'a> InferenceContext<'a> {
239 }; 236 };
240 237
241 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); 238 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
242 Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) 239 Ty::adt_ty(box_adt, Substs::single(inner_ty))
243 } 240 }
244 None => Ty::Unknown, 241 None => Ty::Unknown,
245 }, 242 },