diff --git a/compiler/rustc_error_messages/locales/en-US/session.ftl b/compiler/rustc_error_messages/locales/en-US/session.ftl index 76cae3c81e4..3ea9429a23a 100644 --- a/compiler/rustc_error_messages/locales/en-US/session.ftl +++ b/compiler/rustc_error_messages/locales/en-US/session.ftl @@ -66,3 +66,5 @@ session_crate_name_invalid = crate names cannot start with a `-`, but `{$s}` has session_crate_name_empty = crate name must not be empty session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}` + +session_expr_parentheses_needed = parentheses are required to parse this as an expression diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index e01dafe2102..b5962f76b7f 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -219,3 +219,18 @@ impl IntoDiagnostic<'_> for InvalidCharacterInCrateName<'_> { diag } } + +#[derive(Subdiagnostic)] +#[multipart_suggestion(session::expr_parentheses_needed, applicability = "machine-applicable")] +pub struct ExprParenthesesNeeded { + #[suggestion_part(code = "(")] + pub left: Span, + #[suggestion_part(code = ")")] + pub right: Span, +} + +impl ExprParenthesesNeeded { + pub fn surrounding(s: Span) -> Self { + ExprParenthesesNeeded { left: s.shrink_to_lo(), right: s.shrink_to_hi() } + } +} diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index b9202af2a67..a278a7b5509 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -2,7 +2,9 @@ //! It also serves as an input to the parser itself. use crate::config::CheckCfg; -use crate::errors::{FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError}; +use crate::errors::{ + ExprParenthesesNeeded, FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError, +}; use crate::lint::{ builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId, }; @@ -11,7 +13,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler}; use rustc_errors::{ - fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, + fallback_fluent_bundle, AddToDiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, StashKey, }; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; @@ -325,11 +327,7 @@ impl ParseSess { /// Extend an error with a suggestion to wrap an expression with parentheses to allow the /// parser to continue parsing the following operation as part of the same expression. pub fn expr_parentheses_needed(&self, err: &mut Diagnostic, span: Span) { - err.multipart_suggestion( - "parentheses are required to parse this as an expression", - vec![(span.shrink_to_lo(), "(".to_string()), (span.shrink_to_hi(), ")".to_string())], - Applicability::MachineApplicable, - ); + ExprParenthesesNeeded::surrounding(span).add_to_diagnostic(err); } pub fn save_proc_macro_span(&self, span: Span) -> usize {