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::Expr;
|
||||||
use rustc_hir_analysis::astconv::AstConv;
|
use rustc_hir_analysis::astconv::AstConv;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
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_infer::traits::Obligation;
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_middle::ty::adjustment::{
|
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 {
|
&& let hir::ExprKind::Loop(loop_blk, ..) = expression.kind {
|
||||||
intravisit::walk_block(& mut visitor, loop_blk);
|
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) => {
|
ObligationCauseCode::ReturnValue(id) => {
|
||||||
err = self.report_return_mismatched_types(
|
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);
|
let id = fcx.tcx.hir().parent_id(id);
|
||||||
unsized_return = self.is_return_ty_unsized(fcx, 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(
|
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(
|
fn note_unreachable_loop_return(
|
||||||
&self,
|
&self,
|
||||||
err: &mut Diagnostic,
|
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_copied_or_cloned(err, expr, expr_ty, expected)
|
||||||
|| self.suggest_clone_for_ref(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_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 {
|
if !suggested {
|
||||||
self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected);
|
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
|
/// 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)
|
/// sole field is of the found type, suggest such variants. (Issue #42764)
|
||||||
fn suggest_compatible_variants(
|
fn suggest_compatible_variants(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user