mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 06:41:48 +00:00
Add type_mismatches to InferenceResult and use this in ok-wrapping code fix
This commit is contained in:
parent
d00a285fa7
commit
bacb938ab0
3 changed files with 27 additions and 8 deletions
|
@ -102,14 +102,16 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_results_in_tail_expr(&mut self, id: ExprId, db: &impl HirDatabase) {
|
fn validate_results_in_tail_expr(&mut self, id: ExprId, db: &impl HirDatabase) {
|
||||||
let expr_ty = &self.infer[id];
|
let mismatch = match self.infer.type_mismatch_for_expr(id) {
|
||||||
let func_ty = self.func.ty(db);
|
Some(m) => m,
|
||||||
let func_sig = func_ty.callable_sig(db).unwrap();
|
None => return,
|
||||||
let ret = func_sig.ret();
|
};
|
||||||
let ret = match ret {
|
|
||||||
|
let ret = match &mismatch.expected {
|
||||||
Ty::Apply(t) => t,
|
Ty::Apply(t) => t,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ret_enum = match ret.ctor {
|
let ret_enum = match ret.ctor {
|
||||||
TypeCtor::Adt(AdtDef::Enum(e)) => e,
|
TypeCtor::Adt(AdtDef::Enum(e)) => e,
|
||||||
_ => return,
|
_ => return,
|
||||||
|
@ -119,7 +121,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let params = &ret.parameters;
|
let params = &ret.parameters;
|
||||||
if params.len() == 2 && ¶ms[0] == expr_ty {
|
if params.len() == 2 && ¶ms[0] == &mismatch.actual {
|
||||||
let source_map = self.func.body_source_map(db);
|
let source_map = self.func.body_source_map(db);
|
||||||
let file_id = self.func.source(db).file_id;
|
let file_id = self.func.source(db).file_id;
|
||||||
let parse = db.parse(file_id.original_file(db));
|
let parse = db.parse(file_id.original_file(db));
|
||||||
|
|
|
@ -516,7 +516,7 @@ impl Ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> {
|
fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> {
|
||||||
match self {
|
match self {
|
||||||
Ty::Apply(a_ty) => match a_ty.ctor {
|
Ty::Apply(a_ty) => match a_ty.ctor {
|
||||||
TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)),
|
TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)),
|
||||||
|
|
|
@ -106,6 +106,13 @@ impl Default for BindingMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A mismatch between an expected and an inferred type.
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
|
pub struct TypeMismatch {
|
||||||
|
pub expected: Ty,
|
||||||
|
pub actual: Ty,
|
||||||
|
}
|
||||||
|
|
||||||
/// The result of type inference: A mapping from expressions and patterns to types.
|
/// The result of type inference: A mapping from expressions and patterns to types.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Default)]
|
#[derive(Clone, PartialEq, Eq, Debug, Default)]
|
||||||
pub struct InferenceResult {
|
pub struct InferenceResult {
|
||||||
|
@ -120,6 +127,7 @@ pub struct InferenceResult {
|
||||||
diagnostics: Vec<InferenceDiagnostic>,
|
diagnostics: Vec<InferenceDiagnostic>,
|
||||||
pub(super) type_of_expr: ArenaMap<ExprId, Ty>,
|
pub(super) type_of_expr: ArenaMap<ExprId, Ty>,
|
||||||
pub(super) type_of_pat: ArenaMap<PatId, Ty>,
|
pub(super) type_of_pat: ArenaMap<PatId, Ty>,
|
||||||
|
pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InferenceResult {
|
impl InferenceResult {
|
||||||
|
@ -141,6 +149,9 @@ impl InferenceResult {
|
||||||
pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> {
|
pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> {
|
||||||
self.assoc_resolutions.get(&id.into()).copied()
|
self.assoc_resolutions.get(&id.into()).copied()
|
||||||
}
|
}
|
||||||
|
pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
|
||||||
|
self.type_mismatches.get(expr)
|
||||||
|
}
|
||||||
pub(crate) fn add_diagnostics(
|
pub(crate) fn add_diagnostics(
|
||||||
&self,
|
&self,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
|
@ -1345,9 +1356,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
};
|
};
|
||||||
// use a new type variable if we got Ty::Unknown here
|
// use a new type variable if we got Ty::Unknown here
|
||||||
let ty = self.insert_type_vars_shallow(ty);
|
let ty = self.insert_type_vars_shallow(ty);
|
||||||
self.unify(&ty, &expected.ty);
|
let could_unify = self.unify(&ty, &expected.ty);
|
||||||
let ty = self.resolve_ty_as_possible(&mut vec![], ty);
|
let ty = self.resolve_ty_as_possible(&mut vec![], ty);
|
||||||
self.write_expr_ty(tgt_expr, ty.clone());
|
self.write_expr_ty(tgt_expr, ty.clone());
|
||||||
|
if !could_unify {
|
||||||
|
self.result.type_mismatches.insert(
|
||||||
|
tgt_expr,
|
||||||
|
TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() },
|
||||||
|
);
|
||||||
|
}
|
||||||
ty
|
ty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue