about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl6
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs26
3 files changed, 36 insertions, 19 deletions
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index 2281343e250..034ffc17a7a 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -81,6 +81,12 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte
 hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}`
 hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}`
 
+hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression
+hir_typeck_remove_semi_for_coerce_expr = this could be implicitly returned but it is a statement, not a tail expression
+hir_typeck_remove_semi_for_coerce_ret = the `match` arms can conform to this return type
+hir_typeck_remove_semi_for_coerce_semi = the `match` is a statement because of this semicolon, consider removing it
+hir_typeck_remove_semi_for_coerce_suggestion = remove this semicolon
+
 hir_typeck_return_stmt_outside_of_fn_body =
     {$statement_kind} statement outside of function body
     .encl_body_label = the {$statement_kind} is part of this body...
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 7ad9f51ba70..3319b52e246 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -1,6 +1,6 @@
 use crate::coercion::{AsCoercionSite, CoerceMany};
 use crate::{Diverges, Expectation, FnCtxt, Needs};
-use rustc_errors::{Applicability, Diagnostic, MultiSpan};
+use rustc_errors::Diagnostic;
 use rustc_hir::{self as hir, ExprKind};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::traits::Obligation;
@@ -225,24 +225,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return;
         }
 
-        let semi_span = expr.span.shrink_to_hi().with_hi(semi_span.hi());
-        let mut ret_span: MultiSpan = semi_span.into();
-        ret_span.push_span_label(
-            expr.span,
-            "this could be implicitly returned but it is a statement, not a tail expression",
-        );
-        ret_span.push_span_label(ret, "the `match` arms can conform to this return type");
-        ret_span.push_span_label(
-            semi_span,
-            "the `match` is a statement because of this semicolon, consider removing it",
-        );
-        diag.span_note(ret_span, "you might have meant to return the `match` expression");
-        diag.tool_only_span_suggestion(
-            semi_span,
-            "remove this semicolon",
-            "",
-            Applicability::MaybeIncorrect,
-        );
+        let semi = expr.span.shrink_to_hi().with_hi(semi_span.hi());
+        let sugg = crate::errors::RemoveSemiForCoerce { expr: expr.span, ret, semi };
+        diag.subdiagnostic(sugg);
     }
 
     /// When the previously checked expression (the scrutinee) diverges,
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 054d23c71d4..255fe5e0206 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -292,6 +292,32 @@ pub enum OptionResultRefMismatch {
     // },
 }
 
+pub struct RemoveSemiForCoerce {
+    pub expr: Span,
+    pub ret: Span,
+    pub semi: Span,
+}
+
+impl AddToDiagnostic for RemoveSemiForCoerce {
+    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
+    where
+        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
+    {
+        let mut multispan: MultiSpan = self.semi.into();
+        multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr);
+        multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret);
+        multispan.push_span_label(self.semi, fluent::hir_typeck_remove_semi_for_coerce_semi);
+        diag.span_note(multispan, fluent::hir_typeck_remove_semi_for_coerce);
+
+        diag.tool_only_span_suggestion(
+            self.semi,
+            fluent::hir_typeck_remove_semi_for_coerce_suggestion,
+            "",
+            Applicability::MaybeIncorrect,
+        );
+    }
+}
+
 #[derive(Diagnostic)]
 #[diag(hir_typeck_const_select_must_be_const)]
 #[help]