about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs38
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs33
-rw-r--r--compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl17
3 files changed, 63 insertions, 25 deletions
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 24115237bd9..3644e664ceb 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -1,6 +1,6 @@
 use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic};
 use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
-use rustc_span::{Span, Symbol};
+use rustc_span::{symbol::Ident, Span, Symbol};
 
 #[derive(SessionDiagnostic, Clone, Copy)]
 #[diag(ast_lowering::generic_type_with_parentheses, code = "E0214")]
@@ -270,3 +270,39 @@ pub struct RegisterConflict<'a> {
     #[help]
     pub in_out: Option<Span>,
 }
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[help]
+#[error(ast_lowering::sub_tuple_binding)]
+pub struct SubTupleBinding<'a> {
+    #[primary_span]
+    #[label]
+    #[suggestion_verbose(
+        ast_lowering::sub_tuple_binding_suggestion,
+        code = "..",
+        applicability = "maybe-incorrect"
+    )]
+    pub span: Span,
+    pub ident: Ident,
+    pub ident_name: Symbol,
+    pub ctx: &'a str,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[error(ast_lowering::extra_double_dot)]
+pub struct ExtraDoubleDot<'a> {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    #[label(ast_lowering::previously_used_here)]
+    pub prev_span: Span,
+    pub ctx: &'a str,
+}
+
+#[derive(SessionDiagnostic, Clone, Copy)]
+#[note]
+#[error(ast_lowering::misplaced_double_dot)]
+pub struct MisplacedDoubleDot {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 51f67e505f4..abe9b354252 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -1,3 +1,4 @@
+use super::errors::{ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding};
 use super::ResolverAstLoweringExt;
 use super::{ImplTraitContext, LoweringContext, ParamMode};
 use crate::ImplTraitPosition;
@@ -5,7 +6,6 @@ use crate::ImplTraitPosition;
 use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_span::symbol::Ident;
@@ -134,20 +134,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 // This is not allowed as a sub-tuple pattern
                 PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => {
                     let sp = pat.span;
-                    self.diagnostic()
-                        .struct_span_err(
-                            sp,
-                            &format!("`{} @` is not allowed in a {}", ident.name, ctx),
-                        )
-                        .span_label(sp, "this is only allowed in slice patterns")
-                        .help("remove this and bind each tuple field independently")
-                        .span_suggestion_verbose(
-                            sp,
-                            &format!("if you don't need to use the contents of {}, discard the tuple's remaining fields", ident),
-                            "..",
-                            Applicability::MaybeIncorrect,
-                        )
-                        .emit();
+                    self.tcx.sess.emit_err(SubTupleBinding {
+                        span: sp,
+                        ident_name: ident.name,
+                        ident,
+                        ctx,
+                    });
                 }
                 _ => {}
             }
@@ -296,19 +288,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
     /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
     pub(crate) fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) {
-        self.diagnostic()
-            .struct_span_err(sp, &format!("`..` can only be used once per {} pattern", ctx))
-            .span_label(sp, &format!("can only be used once per {} pattern", ctx))
-            .span_label(prev_sp, "previously used here")
-            .emit();
+        self.tcx.sess.emit_err(ExtraDoubleDot { span: sp, prev_span: prev_sp, ctx });
     }
 
     /// Used to ban the `..` pattern in places it shouldn't be semantically.
     fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind<'hir> {
-        self.diagnostic()
-            .struct_span_err(sp, "`..` patterns are not allowed here")
-            .note("only allowed in tuple, tuple struct, and slice patterns")
-            .emit();
+        self.tcx.sess.emit_err(MisplacedDoubleDot { span: sp });
 
         // We're not in a list context so `..` can be reasonably treated
         // as `_` because it should always be valid and roughly matches the
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl
index 592e303b53f..438fbd8e57b 100644
--- a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl
@@ -103,3 +103,20 @@ ast_lowering_register_conflict =
 ast_lowering_register1 = register `{$reg1_name}`
 
 ast_lowering_register2 = register `{$reg2_name}`
+
+ast_lowering_sub_tuple_binding =
+    `{$ident_name} @` is not allowed in a {$ctx}
+    .label = this is only allowed in slice patterns
+    .help = remove this and bind each tuple field independently
+
+ast_lowering_sub_tuple_binding_suggestion = if you don't need to use the contents of {$ident}, discard the tuple's remaining fields
+
+ast_lowering_extra_double_dot =
+    `..` can only be used once per {$ctx} pattern
+    .label = can only be used once per {$ctx} pattern
+
+ast_lowering_previously_used_here = previously used here
+
+ast_lowering_misplaced_double_dot =
+    `..` patterns are not allowed here
+    .note = only allowed in tuple, tuple struct, and slice patterns