diff options
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index e150d7fd8..1ee40c70a 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -46,7 +46,7 @@ use crate::{ | |||
46 | use super::{ | 46 | use super::{ |
47 | Ty, TypableDef, Substs, primitive, op, ApplicationTy, TypeCtor, CallableDef, TraitRef, | 47 | Ty, TypableDef, Substs, primitive, op, ApplicationTy, TypeCtor, CallableDef, TraitRef, |
48 | traits::{Solution, Obligation, Guidance}, | 48 | traits::{Solution, Obligation, Guidance}, |
49 | method_resolution, | 49 | method_resolution, autoderef, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | mod unify; | 52 | mod unify; |
@@ -1074,25 +1074,27 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1074 | } | 1074 | } |
1075 | Expr::Field { expr, name } => { | 1075 | Expr::Field { expr, name } => { |
1076 | let receiver_ty = self.infer_expr(*expr, &Expectation::none()); | 1076 | let receiver_ty = self.infer_expr(*expr, &Expectation::none()); |
1077 | let ty = receiver_ty | 1077 | let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); |
1078 | .autoderef(self.db) | 1078 | let ty = autoderef::autoderef( |
1079 | .find_map(|derefed_ty| match derefed_ty { | 1079 | self.db, |
1080 | Ty::Apply(a_ty) => match a_ty.ctor { | 1080 | &self.resolver.clone(), |
1081 | TypeCtor::Tuple { .. } => { | 1081 | canonicalized.value.clone(), |
1082 | let i = name.to_string().parse::<usize>().ok(); | 1082 | ) |
1083 | i.and_then(|i| a_ty.parameters.0.get(i).cloned()) | 1083 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { |
1084 | } | 1084 | Ty::Apply(a_ty) => match a_ty.ctor { |
1085 | TypeCtor::Adt(AdtDef::Struct(s)) => { | 1085 | TypeCtor::Tuple { .. } => { |
1086 | s.field(self.db, name).map(|field| { | 1086 | let i = name.to_string().parse::<usize>().ok(); |
1087 | self.write_field_resolution(tgt_expr, field); | 1087 | i.and_then(|i| a_ty.parameters.0.get(i).cloned()) |
1088 | field.ty(self.db).subst(&a_ty.parameters) | 1088 | } |
1089 | }) | 1089 | TypeCtor::Adt(AdtDef::Struct(s)) => s.field(self.db, name).map(|field| { |
1090 | } | 1090 | self.write_field_resolution(tgt_expr, field); |
1091 | _ => None, | 1091 | field.ty(self.db).subst(&a_ty.parameters) |
1092 | }, | 1092 | }), |
1093 | _ => None, | 1093 | _ => None, |
1094 | }) | 1094 | }, |
1095 | .unwrap_or(Ty::Unknown); | 1095 | _ => None, |
1096 | }) | ||
1097 | .unwrap_or(Ty::Unknown); | ||
1096 | self.insert_type_vars(ty) | 1098 | self.insert_type_vars(ty) |
1097 | } | 1099 | } |
1098 | Expr::Try { expr } => { | 1100 | Expr::Try { expr } => { |
@@ -1124,10 +1126,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1124 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); | 1126 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1125 | match op { | 1127 | match op { |
1126 | UnaryOp::Deref => { | 1128 | UnaryOp::Deref => { |
1127 | if let Some(derefed_ty) = inner_ty.builtin_deref() { | 1129 | let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); |
1128 | derefed_ty | 1130 | if let Some(derefed_ty) = |
1131 | autoderef::deref(self.db, &self.resolver, &canonicalized.value) | ||
1132 | { | ||
1133 | canonicalized.decanonicalize_ty(derefed_ty.value) | ||
1129 | } else { | 1134 | } else { |
1130 | // FIXME Deref::deref | ||
1131 | Ty::Unknown | 1135 | Ty::Unknown |
1132 | } | 1136 | } |
1133 | } | 1137 | } |