diff options
author | Aleksey Kladov <aleksey.kladov@gmail.com> | 2019-03-21 19:13:11 +0000 |
---|---|---|
committer | Aleksey Kladov <aleksey.kladov@gmail.com> | 2019-03-25 07:52:12 +0000 |
commit | 7e8f17188efcecfdfd1afbbc894a53c65985f836 (patch) | |
tree | aab311a7646f9880adc82607abd227ef07e35d71 /crates/ra_hir/src/ty | |
parent | 4132fbf3a08c9de2e28a50bc29a2c37a7c1a42fc (diff) |
diagnostics
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 23 |
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 | }; |
41 | use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor}; | 42 | use 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 | ||
118 | impl Index<ExprId> for InferenceResult { | 123 | impl 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)); |