aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs31
1 files changed, 24 insertions, 7 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index cca59538a..d94e8154b 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -37,8 +37,8 @@ use crate::{
37 code_model::{ModuleDef::Trait, TypeAlias}, 37 code_model::{ModuleDef::Trait, TypeAlias},
38 diagnostics::DiagnosticSink, 38 diagnostics::DiagnosticSink,
39 expr::{ 39 expr::{
40 self, Array, BinaryOp, BindingAnnotation, Body, Expr, ExprId, FieldPat, Literal, Pat, 40 self, Array, BinaryOp, BindingAnnotation, Body, Expr, ExprId, Literal, Pat, PatId,
41 PatId, Statement, UnaryOp, 41 RecordFieldPat, Statement, UnaryOp,
42 }, 42 },
43 generics::{GenericParams, HasGenericParams}, 43 generics::{GenericParams, HasGenericParams},
44 name, 44 name,
@@ -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)]
111pub 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)]
111pub struct InferenceResult { 118pub 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
125impl InferenceResult { 133impl 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,
@@ -705,10 +716,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
705 ty 716 ty
706 } 717 }
707 718
708 fn infer_struct_pat( 719 fn infer_record_pat(
709 &mut self, 720 &mut self,
710 path: Option<&Path>, 721 path: Option<&Path>,
711 subpats: &[FieldPat], 722 subpats: &[RecordFieldPat],
712 expected: &Ty, 723 expected: &Ty,
713 default_bm: BindingMode, 724 default_bm: BindingMode,
714 id: PatId, 725 id: PatId,
@@ -800,7 +811,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
800 self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) 811 self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm)
801 } 812 }
802 Pat::Struct { path: ref p, args: ref fields } => { 813 Pat::Struct { path: ref p, args: ref fields } => {
803 self.infer_struct_pat(p.as_ref(), fields, expected, default_bm, pat) 814 self.infer_record_pat(p.as_ref(), fields, expected, default_bm, pat)
804 } 815 }
805 Pat::Path(path) => { 816 Pat::Path(path) => {
806 // FIXME use correct resolver for the surrounding expression 817 // FIXME use correct resolver for the surrounding expression
@@ -1103,7 +1114,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1103 } 1114 }
1104 Ty::simple(TypeCtor::Never) 1115 Ty::simple(TypeCtor::Never)
1105 } 1116 }
1106 Expr::StructLit { path, fields, spread } => { 1117 Expr::RecordLit { path, fields, spread } => {
1107 let (ty, def_id) = self.resolve_variant(path.as_ref()); 1118 let (ty, def_id) = self.resolve_variant(path.as_ref());
1108 if let Some(variant) = def_id { 1119 if let Some(variant) = def_id {
1109 self.write_variant_resolution(tgt_expr.into(), variant); 1120 self.write_variant_resolution(tgt_expr.into(), variant);
@@ -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