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.rs34
1 files changed, 16 insertions, 18 deletions
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index d974f805b..eb099311c 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -3,17 +3,17 @@
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; 13use test_utils::mark;
14 14
15use super::{BindingMode, Expectation, InferenceContext}; 15use super::{BindingMode, Expectation, InferenceContext};
16use crate::{utils::variant_data, Substs, Ty, TypeCtor}; 16use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty};
17 17
18impl<'a> InferenceContext<'a> { 18impl<'a> InferenceContext<'a> {
19 fn infer_tuple_struct_pat( 19 fn infer_tuple_struct_pat(
@@ -32,7 +32,7 @@ impl<'a> InferenceContext<'a> {
32 } 32 }
33 self.unify(&ty, expected); 33 self.unify(&ty, expected);
34 34
35 let substs = ty.substs().unwrap_or_else(Substs::empty); 35 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
36 36
37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
38 let (pre, post) = match ellipsis { 38 let (pre, post) = match ellipsis {
@@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> {
71 71
72 self.unify(&ty, expected); 72 self.unify(&ty, expected);
73 73
74 let substs = ty.substs().unwrap_or_else(Substs::empty); 74 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
75 75
76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
77 for subpat in subpats { 77 for subpat in subpats {
@@ -103,7 +103,7 @@ impl<'a> InferenceContext<'a> {
103 expected = inner; 103 expected = inner;
104 default_bm = match default_bm { 104 default_bm = match default_bm {
105 BindingMode::Move => BindingMode::Ref(mutability), 105 BindingMode::Move => BindingMode::Ref(mutability),
106 BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared), 106 BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not),
107 BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability), 107 BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability),
108 } 108 }
109 } 109 }
@@ -138,10 +138,7 @@ impl<'a> InferenceContext<'a> {
138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
140 140
141 Ty::apply( 141 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 } 142 }
146 Pat::Or(ref pats) => { 143 Pat::Or(ref pats) => {
147 if let Some((first_pat, rest)) = pats.split_first() { 144 if let Some((first_pat, rest)) = pats.split_first() {
@@ -155,9 +152,10 @@ impl<'a> InferenceContext<'a> {
155 } 152 }
156 } 153 }
157 Pat::Ref { pat, mutability } => { 154 Pat::Ref { pat, mutability } => {
155 let mutability = lower_to_chalk_mutability(*mutability);
158 let expectation = match expected.as_reference() { 156 let expectation = match expected.as_reference() {
159 Some((inner_ty, exp_mut)) => { 157 Some((inner_ty, exp_mut)) => {
160 if *mutability != exp_mut { 158 if mutability != exp_mut {
161 // FIXME: emit type error? 159 // FIXME: emit type error?
162 } 160 }
163 inner_ty 161 inner_ty
@@ -165,7 +163,7 @@ impl<'a> InferenceContext<'a> {
165 _ => &Ty::Unknown, 163 _ => &Ty::Unknown,
166 }; 164 };
167 let subty = self.infer_pat(*pat, expectation, default_bm); 165 let subty = self.infer_pat(*pat, expectation, default_bm);
168 Ty::apply_one(TypeCtor::Ref(*mutability), subty) 166 Ty::Ref(mutability, Substs::single(subty))
169 } 167 }
170 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 168 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
171 p.as_ref(), 169 p.as_ref(),
@@ -198,7 +196,7 @@ impl<'a> InferenceContext<'a> {
198 196
199 let bound_ty = match mode { 197 let bound_ty = match mode {
200 BindingMode::Ref(mutability) => { 198 BindingMode::Ref(mutability) => {
201 Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) 199 Ty::Ref(mutability, Substs::single(inner_ty.clone()))
202 } 200 }
203 BindingMode::Move => inner_ty.clone(), 201 BindingMode::Move => inner_ty.clone(),
204 }; 202 };
@@ -207,17 +205,17 @@ impl<'a> InferenceContext<'a> {
207 return inner_ty; 205 return inner_ty;
208 } 206 }
209 Pat::Slice { prefix, slice, suffix } => { 207 Pat::Slice { prefix, slice, suffix } => {
210 let (container_ty, elem_ty) = match &expected { 208 let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected {
211 ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), 209 Ty::Array(st) => (Ty::Array, st.as_single().clone()),
212 ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), 210 Ty::Slice(st) => (Ty::Slice, st.as_single().clone()),
213 _ => (TypeCtor::Slice, Ty::Unknown), 211 _ => (Ty::Slice, Ty::Unknown),
214 }; 212 };
215 213
216 for pat_id in prefix.iter().chain(suffix) { 214 for pat_id in prefix.iter().chain(suffix) {
217 self.infer_pat(*pat_id, &elem_ty, default_bm); 215 self.infer_pat(*pat_id, &elem_ty, default_bm);
218 } 216 }
219 217
220 let pat_ty = Ty::apply_one(container_ty, elem_ty); 218 let pat_ty = container_ty(Substs::single(elem_ty));
221 if let Some(slice_pat_id) = slice { 219 if let Some(slice_pat_id) = slice {
222 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 220 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
223 } 221 }
@@ -239,7 +237,7 @@ impl<'a> InferenceContext<'a> {
239 }; 237 };
240 238
241 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); 239 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
242 Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) 240 Ty::Adt(box_adt, Substs::single(inner_ty))
243 } 241 }
244 None => Ty::Unknown, 242 None => Ty::Unknown,
245 }, 243 },