Skip to content

Commit ddd9a9f

Browse files
committed
Add call in emit_type_mismatch_suggestions
1 parent d5a1609 commit ddd9a9f

File tree

2 files changed

+42
-46
lines changed

2 files changed

+42
-46
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use rustc_hir::intravisit::{self, Visitor};
4545
use rustc_hir::Expr;
4646
use rustc_hir_analysis::astconv::AstConv;
4747
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
48-
use rustc_infer::infer::{Coercion, InferOk, InferResult, TyCtxtInferExt};
48+
use rustc_infer::infer::{Coercion, InferOk, InferResult};
4949
use rustc_infer::traits::Obligation;
5050
use rustc_middle::lint::in_external_macro;
5151
use rustc_middle::ty::adjustment::{
@@ -1565,9 +1565,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
15651565
&& let hir::ExprKind::Loop(loop_blk, ..) = expression.kind {
15661566
intravisit::walk_block(& mut visitor, loop_blk);
15671567
}
1568-
if let Some(expr) = expression {
1569-
self.note_result_coercion(fcx, &mut err, expr, expected, found);
1570-
}
15711568
}
15721569
ObligationCauseCode::ReturnValue(id) => {
15731570
err = self.report_return_mismatched_types(
@@ -1584,9 +1581,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
15841581
let id = fcx.tcx.hir().parent_id(id);
15851582
unsized_return = self.is_return_ty_unsized(fcx, id);
15861583
}
1587-
if let Some(expr) = expression {
1588-
self.note_result_coercion(fcx, &mut err, expr, expected, found);
1589-
}
15901584
}
15911585
_ => {
15921586
err = fcx.err_ctxt().report_mismatched_types(
@@ -1626,44 +1620,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
16261620
}
16271621
}
16281622

1629-
fn note_result_coercion(
1630-
&self,
1631-
fcx: &FnCtxt<'_, 'tcx>,
1632-
err: &mut Diagnostic,
1633-
expr: &hir::Expr<'tcx>,
1634-
expected: Ty<'tcx>,
1635-
found: Ty<'tcx>,
1636-
) {
1637-
let ty::Adt(e, substs_e) = expected.kind() else { return; };
1638-
let ty::Adt(f, substs_f) = found.kind() else { return; };
1639-
if e.did() != f.did() {
1640-
return;
1641-
}
1642-
if Some(e.did()) != fcx.tcx.get_diagnostic_item(sym::Result) {
1643-
return;
1644-
}
1645-
let e = substs_e.type_at(1);
1646-
let f = substs_f.type_at(1);
1647-
if fcx
1648-
.infcx
1649-
.type_implements_trait(
1650-
fcx.tcx.get_diagnostic_item(sym::Into).unwrap(),
1651-
[fcx.tcx.erase_regions(f), fcx.tcx.erase_regions(e)],
1652-
fcx.param_env,
1653-
)
1654-
.must_apply_modulo_regions()
1655-
{
1656-
err.multipart_suggestion(
1657-
"you can rely on the implicit conversion that `?` does to transform the error type",
1658-
vec![
1659-
(expr.span.shrink_to_lo(), "Ok(".to_string()),
1660-
(expr.span.shrink_to_hi(), "?)".to_string()),
1661-
],
1662-
Applicability::MaybeIncorrect,
1663-
);
1664-
}
1665-
}
1666-
16671623
fn note_unreachable_loop_return(
16681624
&self,
16691625
err: &mut Diagnostic,

compiler/rustc_hir_typeck/src/demand.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5959
|| self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
6060
|| self.suggest_clone_for_ref(err, expr, expr_ty, expected)
6161
|| self.suggest_into(err, expr, expr_ty, expected)
62-
|| self.suggest_floating_point_literal(err, expr, expected);
62+
|| self.suggest_floating_point_literal(err, expr, expected)
63+
|| self.note_result_coercion(err, expr, expected, expr_ty);
6364
if !suggested {
6465
self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected);
6566
}
@@ -697,6 +698,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
697698
);
698699
}
699700

701+
pub(crate) fn note_result_coercion(
702+
&self,
703+
err: &mut Diagnostic,
704+
expr: &hir::Expr<'tcx>,
705+
expected: Ty<'tcx>,
706+
found: Ty<'tcx>,
707+
) -> bool {
708+
let ty::Adt(e, substs_e) = expected.kind() else { return false; };
709+
let ty::Adt(f, substs_f) = found.kind() else { return false; };
710+
if e.did() != f.did() {
711+
return false;
712+
}
713+
if Some(e.did()) != self.tcx.get_diagnostic_item(sym::Result) {
714+
return false;
715+
}
716+
let e = substs_e.type_at(1);
717+
let f = substs_f.type_at(1);
718+
if self
719+
.infcx
720+
.type_implements_trait(
721+
self.tcx.get_diagnostic_item(sym::Into).unwrap(),
722+
[self.tcx.erase_regions(f), self.tcx.erase_regions(e)],
723+
self.param_env,
724+
)
725+
.must_apply_modulo_regions()
726+
{
727+
err.multipart_suggestion(
728+
"you can rely on the implicit conversion that `?` does to transform the error type",
729+
vec![
730+
(expr.span.shrink_to_lo(), "Ok(".to_string()),
731+
(expr.span.shrink_to_hi(), "?)".to_string()),
732+
],
733+
Applicability::MaybeIncorrect,
734+
);
735+
return true;
736+
}
737+
false
738+
}
739+
700740
/// If the expected type is an enum (Issue #55250) with any variants whose
701741
/// sole field is of the found type, suggest such variants. (Issue #42764)
702742
fn suggest_compatible_variants(

0 commit comments

Comments
 (0)