Skip to content

Commit bacb938

Browse files
theotherphilmatklad
authored andcommitted
Add type_mismatches to InferenceResult and use this in ok-wrapping code fix
1 parent d00a285 commit bacb938

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

crates/ra_hir/src/expr/validation.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,16 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
102102
}
103103

104104
fn validate_results_in_tail_expr(&mut self, id: ExprId, db: &impl HirDatabase) {
105-
let expr_ty = &self.infer[id];
106-
let func_ty = self.func.ty(db);
107-
let func_sig = func_ty.callable_sig(db).unwrap();
108-
let ret = func_sig.ret();
109-
let ret = match ret {
105+
let mismatch = match self.infer.type_mismatch_for_expr(id) {
106+
Some(m) => m,
107+
None => return,
108+
};
109+
110+
let ret = match &mismatch.expected {
110111
Ty::Apply(t) => t,
111112
_ => return,
112113
};
114+
113115
let ret_enum = match ret.ctor {
114116
TypeCtor::Adt(AdtDef::Enum(e)) => e,
115117
_ => return,
@@ -119,7 +121,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
119121
return;
120122
}
121123
let params = &ret.parameters;
122-
if params.len() == 2 && &params[0] == expr_ty {
124+
if params.len() == 2 && &params[0] == &mismatch.actual {
123125
let source_map = self.func.body_source_map(db);
124126
let file_id = self.func.source(db).file_id;
125127
let parse = db.parse(file_id.original_file(db));

crates/ra_hir/src/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ impl Ty {
516516
}
517517
}
518518

519-
pub fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> {
519+
fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> {
520520
match self {
521521
Ty::Apply(a_ty) => match a_ty.ctor {
522522
TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)),

crates/ra_hir/src/ty/infer.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ impl Default for BindingMode {
106106
}
107107
}
108108

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+
109116
/// The result of type inference: A mapping from expressions and patterns to types.
110117
#[derive(Clone, PartialEq, Eq, Debug, Default)]
111118
pub struct InferenceResult {
@@ -120,6 +127,7 @@ pub struct InferenceResult {
120127
diagnostics: Vec<InferenceDiagnostic>,
121128
pub(super) type_of_expr: ArenaMap<ExprId, Ty>,
122129
pub(super) type_of_pat: ArenaMap<PatId, Ty>,
130+
pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>,
123131
}
124132

125133
impl InferenceResult {
@@ -141,6 +149,9 @@ impl InferenceResult {
141149
pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> {
142150
self.assoc_resolutions.get(&id.into()).copied()
143151
}
152+
pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
153+
self.type_mismatches.get(expr)
154+
}
144155
pub(crate) fn add_diagnostics(
145156
&self,
146157
db: &impl HirDatabase,
@@ -1345,9 +1356,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
13451356
};
13461357
// use a new type variable if we got Ty::Unknown here
13471358
let ty = self.insert_type_vars_shallow(ty);
1348-
self.unify(&ty, &expected.ty);
1359+
let could_unify = self.unify(&ty, &expected.ty);
13491360
let ty = self.resolve_ty_as_possible(&mut vec![], ty);
13501361
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+
}
13511368
ty
13521369
}
13531370

0 commit comments

Comments
 (0)