diff options
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index b33de5687..d94e8154b 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -106,6 +106,13 @@ impl Default for BindingMode { | |||
106 | } | 106 | } |
107 | } | 107 | } |
108 | 108 | ||
109 | /// A mismatch between an expected and an inferred type. | ||
110 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
111 | pub struct TypeMismatch { | ||
112 | pub expected: Ty, | ||
113 | pub actual: Ty, | ||
114 | } | ||
115 | |||
109 | /// The result of type inference: A mapping from expressions and patterns to types. | 116 | /// The result of type inference: A mapping from expressions and patterns to types. |
110 | #[derive(Clone, PartialEq, Eq, Debug, Default)] | 117 | #[derive(Clone, PartialEq, Eq, Debug, Default)] |
111 | pub struct InferenceResult { | 118 | pub struct InferenceResult { |
@@ -120,6 +127,7 @@ pub struct InferenceResult { | |||
120 | diagnostics: Vec<InferenceDiagnostic>, | 127 | diagnostics: Vec<InferenceDiagnostic>, |
121 | pub(super) type_of_expr: ArenaMap<ExprId, Ty>, | 128 | pub(super) type_of_expr: ArenaMap<ExprId, Ty>, |
122 | pub(super) type_of_pat: ArenaMap<PatId, Ty>, | 129 | pub(super) type_of_pat: ArenaMap<PatId, Ty>, |
130 | pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, | ||
123 | } | 131 | } |
124 | 132 | ||
125 | impl InferenceResult { | 133 | impl InferenceResult { |
@@ -141,6 +149,9 @@ impl InferenceResult { | |||
141 | pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> { | 149 | pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> { |
142 | self.assoc_resolutions.get(&id.into()).copied() | 150 | self.assoc_resolutions.get(&id.into()).copied() |
143 | } | 151 | } |
152 | pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { | ||
153 | self.type_mismatches.get(expr) | ||
154 | } | ||
144 | pub(crate) fn add_diagnostics( | 155 | pub(crate) fn add_diagnostics( |
145 | &self, | 156 | &self, |
146 | db: &impl HirDatabase, | 157 | db: &impl HirDatabase, |
@@ -1345,9 +1356,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1345 | }; | 1356 | }; |
1346 | // use a new type variable if we got Ty::Unknown here | 1357 | // use a new type variable if we got Ty::Unknown here |
1347 | let ty = self.insert_type_vars_shallow(ty); | 1358 | let ty = self.insert_type_vars_shallow(ty); |
1348 | self.unify(&ty, &expected.ty); | 1359 | let could_unify = self.unify(&ty, &expected.ty); |
1349 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); | 1360 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); |
1350 | self.write_expr_ty(tgt_expr, ty.clone()); | 1361 | self.write_expr_ty(tgt_expr, ty.clone()); |
1362 | if !could_unify { | ||
1363 | self.result.type_mismatches.insert( | ||
1364 | tgt_expr, | ||
1365 | TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, | ||
1366 | ); | ||
1367 | } | ||
1351 | ty | 1368 | ty |
1352 | } | 1369 | } |
1353 | 1370 | ||