From b663464ea0ffbf55acaf8de292902c3aa77c68b5 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 15 Sep 2023 00:45:09 +0000 Subject: [PATCH] Make 'remove semi to coerce match' diagnostic translatable --- compiler/rustc_hir_typeck/messages.ftl | 6 ++++++ compiler/rustc_hir_typeck/src/_match.rs | 23 ++++------------------ compiler/rustc_hir_typeck/src/errors.rs | 26 +++++++++++++++++++++++++ 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(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]