diff options
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 269b5162e..02708ba0f 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -37,7 +37,8 @@ use crate::{ | |||
37 | adt::VariantDef, | 37 | adt::VariantDef, |
38 | resolve::{Resolver, Resolution}, | 38 | resolve::{Resolver, Resolution}, |
39 | nameres::Namespace, | 39 | nameres::Namespace, |
40 | diagnostics::FunctionDiagnostic, | 40 | ty::infer::diagnostics::InferenceDiagnostic, |
41 | diagnostics::Diagnostics, | ||
41 | }; | 42 | }; |
42 | use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor}; | 43 | use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor}; |
43 | 44 | ||
@@ -97,7 +98,7 @@ pub struct InferenceResult { | |||
97 | field_resolutions: FxHashMap<ExprId, StructField>, | 98 | field_resolutions: FxHashMap<ExprId, StructField>, |
98 | /// For each associated item record what it resolves to | 99 | /// For each associated item record what it resolves to |
99 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, | 100 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, |
100 | diagnostics: Vec<FunctionDiagnostic>, | 101 | diagnostics: Vec<InferenceDiagnostic>, |
101 | pub(super) type_of_expr: ArenaMap<ExprId, Ty>, | 102 | pub(super) type_of_expr: ArenaMap<ExprId, Ty>, |
102 | pub(super) type_of_pat: ArenaMap<PatId, Ty>, | 103 | pub(super) type_of_pat: ArenaMap<PatId, Ty>, |
103 | } | 104 | } |
@@ -115,8 +116,13 @@ impl InferenceResult { | |||
115 | pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> { | 116 | pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> { |
116 | self.assoc_resolutions.get(&id.into()).map(|it| *it) | 117 | self.assoc_resolutions.get(&id.into()).map(|it| *it) |
117 | } | 118 | } |
118 | pub(crate) fn diagnostics(&self) -> Vec<FunctionDiagnostic> { | 119 | pub(crate) fn add_diagnostics( |
119 | self.diagnostics.clone() | 120 | &self, |
121 | db: &impl HirDatabase, | ||
122 | owner: Function, | ||
123 | diagnostics: &mut Diagnostics, | ||
124 | ) { | ||
125 | self.diagnostics.iter().for_each(|it| it.add_to(db, owner, diagnostics)) | ||
120 | } | 126 | } |
121 | } | 127 | } |
122 | 128 | ||
@@ -148,7 +154,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
148 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, | 154 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, |
149 | type_of_expr: ArenaMap<ExprId, Ty>, | 155 | type_of_expr: ArenaMap<ExprId, Ty>, |
150 | type_of_pat: ArenaMap<PatId, Ty>, | 156 | type_of_pat: ArenaMap<PatId, Ty>, |
151 | diagnostics: Vec<FunctionDiagnostic>, | 157 | diagnostics: Vec<InferenceDiagnostic>, |
152 | /// The return type of the function being inferred. | 158 | /// The return type of the function being inferred. |
153 | return_ty: Ty, | 159 | return_ty: Ty, |
154 | } | 160 | } |
@@ -928,7 +934,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
928 | .and_then(|it| match it.field(self.db, &field.name) { | 934 | .and_then(|it| match it.field(self.db, &field.name) { |
929 | Some(field) => Some(field), | 935 | Some(field) => Some(field), |
930 | None => { | 936 | None => { |
931 | self.diagnostics.push(FunctionDiagnostic::NoSuchField { | 937 | self.diagnostics.push(InferenceDiagnostic::NoSuchField { |
932 | expr: tgt_expr, | 938 | expr: tgt_expr, |
933 | field: field_idx, | 939 | field: field_idx, |
934 | }); | 940 | }); |
@@ -1261,3 +1267,24 @@ impl Expectation { | |||
1261 | Expectation { ty: Ty::Unknown } | 1267 | Expectation { ty: Ty::Unknown } |
1262 | } | 1268 | } |
1263 | } | 1269 | } |
1270 | |||
1271 | mod diagnostics { | ||
1272 | use crate::{expr::ExprId, diagnostics::{Diagnostics, NoSuchField}, HirDatabase, Function}; | ||
1273 | |||
1274 | #[derive(Debug, PartialEq, Eq, Clone)] | ||
1275 | pub(super) enum InferenceDiagnostic { | ||
1276 | NoSuchField { expr: ExprId, field: usize }, | ||
1277 | } | ||
1278 | |||
1279 | impl InferenceDiagnostic { | ||
1280 | pub(super) fn add_to(&self, db: &impl HirDatabase, owner: Function, acc: &mut Diagnostics) { | ||
1281 | match self { | ||
1282 | InferenceDiagnostic::NoSuchField { expr, field } => { | ||
1283 | let (file, _) = owner.source(db); | ||
1284 | let field = owner.body_source_map(db).field_syntax(*expr, *field); | ||
1285 | acc.push(NoSuchField { file, field }) | ||
1286 | } | ||
1287 | } | ||
1288 | } | ||
1289 | } | ||
1290 | } | ||