Add call in emit_type_mismatch_suggestions
This commit is contained in:
parent
d5a1609ec4
commit
ddd9a9fb46
@ -45,7 +45,7 @@ use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::Expr;
|
||||
use rustc_hir_analysis::astconv::AstConv;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::{Coercion, InferOk, InferResult, TyCtxtInferExt};
|
||||
use rustc_infer::infer::{Coercion, InferOk, InferResult};
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::adjustment::{
|
||||
@ -1565,9 +1565,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||
&& let hir::ExprKind::Loop(loop_blk, ..) = expression.kind {
|
||||
intravisit::walk_block(& mut visitor, loop_blk);
|
||||
}
|
||||
if let Some(expr) = expression {
|
||||
self.note_result_coercion(fcx, &mut err, expr, expected, found);
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::ReturnValue(id) => {
|
||||
err = self.report_return_mismatched_types(
|
||||
@ -1584,9 +1581,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||
let id = fcx.tcx.hir().parent_id(id);
|
||||
unsized_return = self.is_return_ty_unsized(fcx, id);
|
||||
}
|
||||
if let Some(expr) = expression {
|
||||
self.note_result_coercion(fcx, &mut err, expr, expected, found);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
err = fcx.err_ctxt().report_mismatched_types(
|
||||
@ -1626,44 +1620,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||
}
|
||||
}
|
||||
|
||||
fn note_result_coercion(
|
||||
&self,
|
||||
fcx: &FnCtxt<'_, 'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
expr: &hir::Expr<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
) {
|
||||
let ty::Adt(e, substs_e) = expected.kind() else { return; };
|
||||
let ty::Adt(f, substs_f) = found.kind() else { return; };
|
||||
if e.did() != f.did() {
|
||||
return;
|
||||
}
|
||||
if Some(e.did()) != fcx.tcx.get_diagnostic_item(sym::Result) {
|
||||
return;
|
||||
}
|
||||
let e = substs_e.type_at(1);
|
||||
let f = substs_f.type_at(1);
|
||||
if fcx
|
||||
.infcx
|
||||
.type_implements_trait(
|
||||
fcx.tcx.get_diagnostic_item(sym::Into).unwrap(),
|
||||
[fcx.tcx.erase_regions(f), fcx.tcx.erase_regions(e)],
|
||||
fcx.param_env,
|
||||
)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
err.multipart_suggestion(
|
||||
"you can rely on the implicit conversion that `?` does to transform the error type",
|
||||
vec![
|
||||
(expr.span.shrink_to_lo(), "Ok(".to_string()),
|
||||
(expr.span.shrink_to_hi(), "?)".to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn note_unreachable_loop_return(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
|
@ -59,7 +59,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|| self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
|
||||
|| self.suggest_clone_for_ref(err, expr, expr_ty, expected)
|
||||
|| self.suggest_into(err, expr, expr_ty, expected)
|
||||
|| self.suggest_floating_point_literal(err, expr, expected);
|
||||
|| self.suggest_floating_point_literal(err, expr, expected)
|
||||
|| self.note_result_coercion(err, expr, expected, expr_ty);
|
||||
if !suggested {
|
||||
self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected);
|
||||
}
|
||||
@ -697,6 +698,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn note_result_coercion(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
expr: &hir::Expr<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
) -> bool {
|
||||
let ty::Adt(e, substs_e) = expected.kind() else { return false; };
|
||||
let ty::Adt(f, substs_f) = found.kind() else { return false; };
|
||||
if e.did() != f.did() {
|
||||
return false;
|
||||
}
|
||||
if Some(e.did()) != self.tcx.get_diagnostic_item(sym::Result) {
|
||||
return false;
|
||||
}
|
||||
let e = substs_e.type_at(1);
|
||||
let f = substs_f.type_at(1);
|
||||
if self
|
||||
.infcx
|
||||
.type_implements_trait(
|
||||
self.tcx.get_diagnostic_item(sym::Into).unwrap(),
|
||||
[self.tcx.erase_regions(f), self.tcx.erase_regions(e)],
|
||||
self.param_env,
|
||||
)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
err.multipart_suggestion(
|
||||
"you can rely on the implicit conversion that `?` does to transform the error type",
|
||||
vec![
|
||||
(expr.span.shrink_to_lo(), "Ok(".to_string()),
|
||||
(expr.span.shrink_to_hi(), "?)".to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// If the expected type is an enum (Issue #55250) with any variants whose
|
||||
/// sole field is of the found type, suggest such variants. (Issue #42764)
|
||||
fn suggest_compatible_variants(
|
||||
|
Loading…
x
Reference in New Issue
Block a user