about summary refs log tree commit diff
path: root/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-07-10 18:55:45 -0400
committerMichael Goulet <michael@errs.io>2024-07-10 18:55:45 -0400
commitdf72e478b0179581c985ec53ebd6a0d14a330366 (patch)
tree3fb4431c5608fd53c11aadec4d9d9fc78f975b39 /compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
parentd81987661a06ae8d49a5f014f81824c655e87768 (diff)
downloadrust-df72e478b0179581c985ec53ebd6a0d14a330366.tar.gz
rust-df72e478b0179581c985ec53ebd6a0d14a330366.zip
Make sure that labels are defined after the primary span in diagnostics
Diffstat (limited to 'compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs')
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs9
1 files changed, 9 insertions, 0 deletions
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index 46bd80c2df6..f93d89d6c0f 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -269,6 +269,7 @@ impl DiagnosticDeriveVariantBuilder {
         let field_binding = &binding_info.binding;
 
         let inner_ty = FieldInnerTy::from_type(&field.ty);
+        let mut seen_label = false;
 
         field
             .attrs
@@ -280,6 +281,14 @@ impl DiagnosticDeriveVariantBuilder {
                 }
 
                 let name = attr.path().segments.last().unwrap().ident.to_string();
+
+                if name == "primary_span" && seen_label {
+                    span_err(attr.span().unwrap(), format!("`#[primary_span]` must be placed before labels, since it overwrites the span of the diagnostic")).emit();
+                }
+                if name == "label" {
+                    seen_label = true;
+                }
+
                 let needs_clone =
                     name == "primary_span" && matches!(inner_ty, FieldInnerTy::Vec(_));
                 let (binding, needs_destructure) = if needs_clone {