aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
authorSergey Parilin <[email protected]>2019-04-02 15:55:14 +0100
committerSergey Parilin <[email protected]>2019-04-02 15:55:14 +0100
commitb74449e9952846a8ea66c3507e52c24348d6dbc9 (patch)
tree00bb1101334b0bf1b189a2e6451cb28e0af959a1 /crates/ra_hir/src/ty/infer.rs
parent9b73f809596e955216dde24fcf921d6985a1a767 (diff)
parent849d7428aa6b733d452b2ebc55ec322d96345f49 (diff)
Merge remote-tracking branch 'upstream/master' into issue961_profiling
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs58
1 files changed, 54 insertions, 4 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index cff7e7481..573115321 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -36,7 +36,9 @@ use crate::{
36 path::{GenericArgs, GenericArg}, 36 path::{GenericArgs, GenericArg},
37 adt::VariantDef, 37 adt::VariantDef,
38 resolve::{Resolver, Resolution}, 38 resolve::{Resolver, Resolution},
39 nameres::Namespace 39 nameres::Namespace,
40 ty::infer::diagnostics::InferenceDiagnostic,
41 diagnostics::DiagnosticSink,
40}; 42};
41use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor}; 43use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor};
42 44
@@ -96,6 +98,7 @@ pub struct InferenceResult {
96 field_resolutions: FxHashMap<ExprId, StructField>, 98 field_resolutions: FxHashMap<ExprId, StructField>,
97 /// For each associated item record what it resolves to 99 /// For each associated item record what it resolves to
98 assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, 100 assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>,
101 diagnostics: Vec<InferenceDiagnostic>,
99 pub(super) type_of_expr: ArenaMap<ExprId, Ty>, 102 pub(super) type_of_expr: ArenaMap<ExprId, Ty>,
100 pub(super) type_of_pat: ArenaMap<PatId, Ty>, 103 pub(super) type_of_pat: ArenaMap<PatId, Ty>,
101} 104}
@@ -113,6 +116,14 @@ impl InferenceResult {
113 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> { 116 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> {
114 self.assoc_resolutions.get(&id.into()).map(|it| *it) 117 self.assoc_resolutions.get(&id.into()).map(|it| *it)
115 } 118 }
119 pub(crate) fn add_diagnostics(
120 &self,
121 db: &impl HirDatabase,
122 owner: Function,
123 sink: &mut DiagnosticSink,
124 ) {
125 self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink))
126 }
116} 127}
117 128
118impl Index<ExprId> for InferenceResult { 129impl Index<ExprId> for InferenceResult {
@@ -143,6 +154,7 @@ struct InferenceContext<'a, D: HirDatabase> {
143 assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, 154 assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>,
144 type_of_expr: ArenaMap<ExprId, Ty>, 155 type_of_expr: ArenaMap<ExprId, Ty>,
145 type_of_pat: ArenaMap<PatId, Ty>, 156 type_of_pat: ArenaMap<PatId, Ty>,
157 diagnostics: Vec<InferenceDiagnostic>,
146 /// The return type of the function being inferred. 158 /// The return type of the function being inferred.
147 return_ty: Ty, 159 return_ty: Ty,
148} 160}
@@ -155,6 +167,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
155 assoc_resolutions: FxHashMap::default(), 167 assoc_resolutions: FxHashMap::default(),
156 type_of_expr: ArenaMap::default(), 168 type_of_expr: ArenaMap::default(),
157 type_of_pat: ArenaMap::default(), 169 type_of_pat: ArenaMap::default(),
170 diagnostics: Vec::default(),
158 var_unification_table: InPlaceUnificationTable::new(), 171 var_unification_table: InPlaceUnificationTable::new(),
159 return_ty: Ty::Unknown, // set in collect_fn_signature 172 return_ty: Ty::Unknown, // set in collect_fn_signature
160 db, 173 db,
@@ -181,6 +194,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
181 assoc_resolutions: self.assoc_resolutions, 194 assoc_resolutions: self.assoc_resolutions,
182 type_of_expr: expr_types, 195 type_of_expr: expr_types,
183 type_of_pat: pat_types, 196 type_of_pat: pat_types,
197 diagnostics: self.diagnostics,
184 } 198 }
185 } 199 }
186 200
@@ -807,7 +821,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
807 } 821 }
808 Expr::MethodCall { receiver, args, method_name, generic_args } => { 822 Expr::MethodCall { receiver, args, method_name, generic_args } => {
809 let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); 823 let receiver_ty = self.infer_expr(*receiver, &Expectation::none());
810 let resolved = receiver_ty.clone().lookup_method(self.db, method_name); 824 let resolved =
825 receiver_ty.clone().lookup_method(self.db, method_name, &self.resolver);
811 let (derefed_receiver_ty, method_ty, def_generics) = match resolved { 826 let (derefed_receiver_ty, method_ty, def_generics) = match resolved {
812 Some((ty, func)) => { 827 Some((ty, func)) => {
813 self.write_method_resolution(tgt_expr, func); 828 self.write_method_resolution(tgt_expr, func);
@@ -915,9 +930,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
915 Expr::StructLit { path, fields, spread } => { 930 Expr::StructLit { path, fields, spread } => {
916 let (ty, def_id) = self.resolve_variant(path.as_ref()); 931 let (ty, def_id) = self.resolve_variant(path.as_ref());
917 let substs = ty.substs().unwrap_or_else(Substs::empty); 932 let substs = ty.substs().unwrap_or_else(Substs::empty);
918 for field in fields { 933 for (field_idx, field) in fields.into_iter().enumerate() {
919 let field_ty = def_id 934 let field_ty = def_id
920 .and_then(|it| it.field(self.db, &field.name)) 935 .and_then(|it| match it.field(self.db, &field.name) {
936 Some(field) => Some(field),
937 None => {
938 self.diagnostics.push(InferenceDiagnostic::NoSuchField {
939 expr: tgt_expr,
940 field: field_idx,
941 });
942 None
943 }
944 })
921 .map_or(Ty::Unknown, |field| field.ty(self.db)) 945 .map_or(Ty::Unknown, |field| field.ty(self.db))
922 .subst(&substs); 946 .subst(&substs);
923 self.infer_expr(field.expr, &Expectation::has_type(field_ty)); 947 self.infer_expr(field.expr, &Expectation::has_type(field_ty));
@@ -1244,3 +1268,29 @@ impl Expectation {
1244 Expectation { ty: Ty::Unknown } 1268 Expectation { ty: Ty::Unknown }
1245 } 1269 }
1246} 1270}
1271
1272mod diagnostics {
1273 use crate::{expr::ExprId, diagnostics::{DiagnosticSink, NoSuchField}, HirDatabase, Function};
1274
1275 #[derive(Debug, PartialEq, Eq, Clone)]
1276 pub(super) enum InferenceDiagnostic {
1277 NoSuchField { expr: ExprId, field: usize },
1278 }
1279
1280 impl InferenceDiagnostic {
1281 pub(super) fn add_to(
1282 &self,
1283 db: &impl HirDatabase,
1284 owner: Function,
1285 sink: &mut DiagnosticSink,
1286 ) {
1287 match self {
1288 InferenceDiagnostic::NoSuchField { expr, field } => {
1289 let (file, _) = owner.source(db);
1290 let field = owner.body_source_map(db).field_syntax(*expr, *field);
1291 sink.push(NoSuchField { file, field })
1292 }
1293 }
1294 }
1295 }
1296}