aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
authorAleksey Kladov <aleksey.kladov@gmail.com>2019-03-21 19:13:11 +0000
committerAleksey Kladov <aleksey.kladov@gmail.com>2019-03-25 07:52:12 +0000
commit7e8f17188efcecfdfd1afbbc894a53c65985f836 (patch)
treeaab311a7646f9880adc82607abd227ef07e35d71 /crates/ra_hir/src/ty
parent4132fbf3a08c9de2e28a50bc29a2c37a7c1a42fc (diff)
diagnostics
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/infer.rs23
1 files changed, 20 insertions, 3 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index cff7e7481..269b5162e 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -36,7 +36,8 @@ 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 diagnostics::FunctionDiagnostic,
40}; 41};
41use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor}; 42use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor};
42 43
@@ -96,6 +97,7 @@ pub struct InferenceResult {
96 field_resolutions: FxHashMap<ExprId, StructField>, 97 field_resolutions: FxHashMap<ExprId, StructField>,
97 /// For each associated item record what it resolves to 98 /// For each associated item record what it resolves to
98 assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, 99 assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>,
100 diagnostics: Vec<FunctionDiagnostic>,
99 pub(super) type_of_expr: ArenaMap<ExprId, Ty>, 101 pub(super) type_of_expr: ArenaMap<ExprId, Ty>,
100 pub(super) type_of_pat: ArenaMap<PatId, Ty>, 102 pub(super) type_of_pat: ArenaMap<PatId, Ty>,
101} 103}
@@ -113,6 +115,9 @@ impl InferenceResult {
113 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> { 115 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> {
114 self.assoc_resolutions.get(&id.into()).map(|it| *it) 116 self.assoc_resolutions.get(&id.into()).map(|it| *it)
115 } 117 }
118 pub(crate) fn diagnostics(&self) -> Vec<FunctionDiagnostic> {
119 self.diagnostics.clone()
120 }
116} 121}
117 122
118impl Index<ExprId> for InferenceResult { 123impl Index<ExprId> for InferenceResult {
@@ -143,6 +148,7 @@ struct InferenceContext<'a, D: HirDatabase> {
143 assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, 148 assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>,
144 type_of_expr: ArenaMap<ExprId, Ty>, 149 type_of_expr: ArenaMap<ExprId, Ty>,
145 type_of_pat: ArenaMap<PatId, Ty>, 150 type_of_pat: ArenaMap<PatId, Ty>,
151 diagnostics: Vec<FunctionDiagnostic>,
146 /// The return type of the function being inferred. 152 /// The return type of the function being inferred.
147 return_ty: Ty, 153 return_ty: Ty,
148} 154}
@@ -155,6 +161,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
155 assoc_resolutions: FxHashMap::default(), 161 assoc_resolutions: FxHashMap::default(),
156 type_of_expr: ArenaMap::default(), 162 type_of_expr: ArenaMap::default(),
157 type_of_pat: ArenaMap::default(), 163 type_of_pat: ArenaMap::default(),
164 diagnostics: Vec::default(),
158 var_unification_table: InPlaceUnificationTable::new(), 165 var_unification_table: InPlaceUnificationTable::new(),
159 return_ty: Ty::Unknown, // set in collect_fn_signature 166 return_ty: Ty::Unknown, // set in collect_fn_signature
160 db, 167 db,
@@ -181,6 +188,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
181 assoc_resolutions: self.assoc_resolutions, 188 assoc_resolutions: self.assoc_resolutions,
182 type_of_expr: expr_types, 189 type_of_expr: expr_types,
183 type_of_pat: pat_types, 190 type_of_pat: pat_types,
191 diagnostics: self.diagnostics,
184 } 192 }
185 } 193 }
186 194
@@ -915,9 +923,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
915 Expr::StructLit { path, fields, spread } => { 923 Expr::StructLit { path, fields, spread } => {
916 let (ty, def_id) = self.resolve_variant(path.as_ref()); 924 let (ty, def_id) = self.resolve_variant(path.as_ref());
917 let substs = ty.substs().unwrap_or_else(Substs::empty); 925 let substs = ty.substs().unwrap_or_else(Substs::empty);
918 for field in fields { 926 for (field_idx, field) in fields.into_iter().enumerate() {
919 let field_ty = def_id 927 let field_ty = def_id
920 .and_then(|it| it.field(self.db, &field.name)) 928 .and_then(|it| match it.field(self.db, &field.name) {
929 Some(field) => Some(field),
930 None => {
931 self.diagnostics.push(FunctionDiagnostic::NoSuchField {
932 expr: tgt_expr,
933 field: field_idx,
934 });
935 None
936 }
937 })
921 .map_or(Ty::Unknown, |field| field.ty(self.db)) 938 .map_or(Ty::Unknown, |field| field.ty(self.db))
922 .subst(&substs); 939 .subst(&substs);
923 self.infer_expr(field.expr, &Expectation::has_type(field_ty)); 940 self.infer_expr(field.expr, &Expectation::has_type(field_ty));