]> git.lizzy.rs Git - rust.git/commitdiff
Add call in `emit_type_mismatch_suggestions`
authorEsteban Küber <esteban@kuber.com.ar>
Sun, 8 Jan 2023 07:14:17 +0000 (07:14 +0000)
committerEsteban Küber <esteban@kuber.com.ar>
Mon, 23 Jan 2023 14:46:59 +0000 (14:46 +0000)
compiler/rustc_hir_typeck/src/coercion.rs
compiler/rustc_hir_typeck/src/demand.rs

index 893d1e88bf8a2660dc039ed5e4a43e3ebebf2bf4..d5f37abb8b4551f01e763ad8dfdfc73afa39e938 100644 (file)
@@ -45,7 +45,7 @@
 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 @@ pub(crate) fn coerce_inner<'a>(
                             && 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 @@ pub(crate) fn coerce_inner<'a>(
                             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 @@ pub(crate) fn coerce_inner<'a>(
         }
     }
 
-    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,
index 665dc8b6a2f2a4ed18091fb4952e550ca82ba30c..b10bb593ead4b04bf046347df1dff284c4029e92 100644 (file)
@@ -59,7 +59,8 @@ pub fn emit_type_mismatch_suggestions(
             || 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 @@ fn annotate_alternative_method_deref(
         );
     }
 
+    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(