aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/infer')
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs42
-rw-r--r--crates/ra_hir/src/ty/infer/pat.rs20
2 files changed, 34 insertions, 28 deletions
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs
index 57f845dfa..f9ededa23 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir/src/ty/infer/expr.rs
@@ -16,9 +16,9 @@ use hir_expand::name::{self, Name};
16use crate::{ 16use crate::{
17 db::HirDatabase, 17 db::HirDatabase,
18 ty::{ 18 ty::{
19 autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, 19 autoderef, method_resolution, op, traits::InEnvironment, utils::variant_data, CallableDef,
20 Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 20 InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs,
21 TypeWalk, Uncertain, 21 TraitRef, Ty, TypeCtor, TypeWalk, Uncertain,
22 }, 22 },
23}; 23};
24 24
@@ -100,7 +100,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
100 let projection = ProjectionPredicate { 100 let projection = ProjectionPredicate {
101 ty: pat_ty.clone(), 101 ty: pat_ty.clone(),
102 projection_ty: ProjectionTy { 102 projection_ty: ProjectionTy {
103 associated_ty: into_iter_item_alias.id, 103 associated_ty: into_iter_item_alias,
104 parameters: Substs::single(iterable_ty), 104 parameters: Substs::single(iterable_ty),
105 }, 105 },
106 }; 106 };
@@ -218,22 +218,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
218 let substs = ty.substs().unwrap_or_else(Substs::empty); 218 let substs = ty.substs().unwrap_or_else(Substs::empty);
219 let field_types = 219 let field_types =
220 def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default(); 220 def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default();
221 let variant_data = def_id.map(|it| variant_data(self.db, it));
221 for (field_idx, field) in fields.iter().enumerate() { 222 for (field_idx, field) in fields.iter().enumerate() {
222 let field_def = def_id.and_then(|it| match it.field(self.db, &field.name) { 223 let field_def =
223 Some(field) => Some(field), 224 variant_data.as_ref().and_then(|it| match it.field(&field.name) {
224 None => { 225 Some(local_id) => {
225 self.push_diagnostic(InferenceDiagnostic::NoSuchField { 226 Some(StructFieldId { parent: def_id.unwrap(), local_id })
226 expr: tgt_expr, 227 }
227 field: field_idx, 228 None => {
228 }); 229 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
229 None 230 expr: tgt_expr,
230 } 231 field: field_idx,
231 }); 232 });
233 None
234 }
235 });
232 if let Some(field_def) = field_def { 236 if let Some(field_def) = field_def {
233 self.result.record_field_resolutions.insert(field.expr, field_def); 237 self.result.record_field_resolutions.insert(field.expr, field_def);
234 } 238 }
235 let field_ty = field_def 239 let field_ty = field_def
236 .map_or(Ty::Unknown, |it| field_types[it.id].clone()) 240 .map_or(Ty::Unknown, |it| field_types[it.local_id].clone())
237 .subst(&substs); 241 .subst(&substs);
238 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 242 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
239 } 243 }
@@ -262,7 +266,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
262 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 266 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
263 let field = StructFieldId { parent: s.into(), local_id }.into(); 267 let field = StructFieldId { parent: s.into(), local_id }.into();
264 self.write_field_resolution(tgt_expr, field); 268 self.write_field_resolution(tgt_expr, field);
265 self.db.field_types(s.into())[field.id] 269 self.db.field_types(s.into())[field.local_id]
266 .clone() 270 .clone()
267 .subst(&a_ty.parameters) 271 .subst(&a_ty.parameters)
268 }) 272 })
@@ -285,7 +289,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
285 let projection = ProjectionPredicate { 289 let projection = ProjectionPredicate {
286 ty: ty.clone(), 290 ty: ty.clone(),
287 projection_ty: ProjectionTy { 291 projection_ty: ProjectionTy {
288 associated_ty: future_future_output_alias.id, 292 associated_ty: future_future_output_alias,
289 parameters: Substs::single(inner_ty), 293 parameters: Substs::single(inner_ty),
290 }, 294 },
291 }; 295 };
@@ -304,7 +308,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
304 let projection = ProjectionPredicate { 308 let projection = ProjectionPredicate {
305 ty: ty.clone(), 309 ty: ty.clone(),
306 projection_ty: ProjectionTy { 310 projection_ty: ProjectionTy {
307 associated_ty: ops_try_ok_alias.id, 311 associated_ty: ops_try_ok_alias,
308 parameters: Substs::single(inner_ty), 312 parameters: Substs::single(inner_ty),
309 }, 313 },
310 }; 314 };
@@ -557,7 +561,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
557 Some((ty, func)) => { 561 Some((ty, func)) => {
558 let ty = canonicalized_receiver.decanonicalize_ty(ty); 562 let ty = canonicalized_receiver.decanonicalize_ty(ty);
559 self.write_method_resolution(tgt_expr, func); 563 self.write_method_resolution(tgt_expr, func);
560 (ty, self.db.value_ty(func.id.into()), Some(self.db.generic_params(func.id.into()))) 564 (ty, self.db.value_ty(func.into()), Some(self.db.generic_params(func.into())))
561 } 565 }
562 None => (receiver_ty, Ty::Unknown, None), 566 None => (receiver_ty, Ty::Unknown, None),
563 }; 567 };
diff --git a/crates/ra_hir/src/ty/infer/pat.rs b/crates/ra_hir/src/ty/infer/pat.rs
index 6dbf03eb2..a14774607 100644
--- a/crates/ra_hir/src/ty/infer/pat.rs
+++ b/crates/ra_hir/src/ty/infer/pat.rs
@@ -14,7 +14,7 @@ use test_utils::tested_by;
14use super::{BindingMode, InferenceContext}; 14use super::{BindingMode, InferenceContext};
15use crate::{ 15use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 ty::{Substs, Ty, TypeCtor, TypeWalk}, 17 ty::{utils::variant_data, Substs, Ty, TypeCtor, TypeWalk},
18}; 18};
19 19
20impl<'a, D: HirDatabase> InferenceContext<'a, D> { 20impl<'a, D: HirDatabase> InferenceContext<'a, D> {
@@ -26,16 +26,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
26 default_bm: BindingMode, 26 default_bm: BindingMode,
27 ) -> Ty { 27 ) -> Ty {
28 let (ty, def) = self.resolve_variant(path); 28 let (ty, def) = self.resolve_variant(path);
29 29 let var_data = def.map(|it| variant_data(self.db, it));
30 self.unify(&ty, expected); 30 self.unify(&ty, expected);
31 31
32 let substs = ty.substs().unwrap_or_else(Substs::empty); 32 let substs = ty.substs().unwrap_or_else(Substs::empty);
33 33
34 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); 34 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default();
35
35 for (i, &subpat) in subpats.iter().enumerate() { 36 for (i, &subpat) in subpats.iter().enumerate() {
36 let expected_ty = def 37 let expected_ty = var_data
37 .and_then(|d| d.field(self.db, &Name::new_tuple_field(i))) 38 .as_ref()
38 .map_or(Ty::Unknown, |field| field_tys[field.id].clone()) 39 .and_then(|d| d.field(&Name::new_tuple_field(i)))
40 .map_or(Ty::Unknown, |field| field_tys[field].clone())
39 .subst(&substs); 41 .subst(&substs);
40 let expected_ty = self.normalize_associated_types_in(expected_ty); 42 let expected_ty = self.normalize_associated_types_in(expected_ty);
41 self.infer_pat(subpat, &expected_ty, default_bm); 43 self.infer_pat(subpat, &expected_ty, default_bm);
@@ -53,6 +55,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
53 id: PatId, 55 id: PatId,
54 ) -> Ty { 56 ) -> Ty {
55 let (ty, def) = self.resolve_variant(path); 57 let (ty, def) = self.resolve_variant(path);
58 let var_data = def.map(|it| variant_data(self.db, it));
56 if let Some(variant) = def { 59 if let Some(variant) = def {
57 self.write_variant_resolution(id.into(), variant); 60 self.write_variant_resolution(id.into(), variant);
58 } 61 }
@@ -63,10 +66,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
63 66
64 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); 67 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default();
65 for subpat in subpats { 68 for subpat in subpats {
66 let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); 69 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name));
67 let expected_ty = matching_field 70 let expected_ty =
68 .map_or(Ty::Unknown, |field| field_tys[field.id].clone()) 71 matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone()).subst(&substs);
69 .subst(&substs);
70 let expected_ty = self.normalize_associated_types_in(expected_ty); 72 let expected_ty = self.normalize_associated_types_in(expected_ty);
71 self.infer_pat(subpat.pat, &expected_ty, default_bm); 73 self.infer_pat(subpat.pat, &expected_ty, default_bm);
72 } 74 }