diff options
Diffstat (limited to 'crates/ra_hir/src/ty/infer')
-rw-r--r-- | crates/ra_hir/src/ty/infer/expr.rs | 42 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/pat.rs | 20 |
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}; | |||
16 | use crate::{ | 16 | use 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; | |||
14 | use super::{BindingMode, InferenceContext}; | 14 | use super::{BindingMode, InferenceContext}; |
15 | use crate::{ | 15 | use 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 | ||
20 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 20 | impl<'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 | } |