about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorJana Dönszelmann <jana@donsz.nl>2025-09-16 11:52:17 -0700
committerJana Dönszelmann <jana@donsz.nl>2025-09-27 19:32:14 +0200
commitb3631e1174e222bf1dadf1549cfd0f717ebf6d64 (patch)
tree10ca9f88ec5f1224947544cfd2d5ca76d09e13d1 /compiler
parentade84871f718ea20a6460d28e82290353b4bf3d2 (diff)
downloadrust-b3631e1174e222bf1dadf1549cfd0f717ebf6d64.tar.gz
rust-b3631e1174e222bf1dadf1549cfd0f717ebf6d64.zip
improve empty attribute diagnostic
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_attr_parsing/messages.ftl10
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs7
-rw-r--r--compiler/rustc_attr_parsing/src/lints.rs18
-rw-r--r--compiler/rustc_attr_parsing/src/session_diagnostics.rs3
-rw-r--r--compiler/rustc_hir/src/lints.rs15
5 files changed, 38 insertions, 15 deletions
diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl
index 81ec17077c1..6c5346e8355 100644
--- a/compiler/rustc_attr_parsing/messages.ftl
+++ b/compiler/rustc_attr_parsing/messages.ftl
@@ -8,7 +8,15 @@ attr_parsing_deprecated_item_suggestion =
 
 attr_parsing_empty_attribute =
     unused attribute
-    .suggestion = remove this attribute
+    .suggestion = {$valid_without_list ->
+        [true] remove these parentheses
+        *[other] remove this attribute
+    }
+    .note = {$valid_without_list ->
+        [true] using `{$attr_path}` with an empty list is equivalent to not using a list at all
+        *[other] using `{$attr_path}` with an empty list has no effect
+    }
+
 
 attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target}
     .help = `#[{$name}]` can {$only}be applied to {$applied}
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index d7ccf3c7806..e8bb4caa416 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -597,7 +597,12 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
     }
 
     pub(crate) fn warn_empty_attribute(&mut self, span: Span) {
-        self.emit_lint(AttributeLintKind::EmptyAttribute { first_span: span }, span);
+        let attr_path = self.attr_path.clone();
+        let valid_without_list = self.template.word;
+        self.emit_lint(
+            AttributeLintKind::EmptyAttribute { first_span: span, attr_path, valid_without_list },
+            span,
+        );
     }
 }
 
diff --git a/compiler/rustc_attr_parsing/src/lints.rs b/compiler/rustc_attr_parsing/src/lints.rs
index ab8ba0daf1f..3a2a3704669 100644
--- a/compiler/rustc_attr_parsing/src/lints.rs
+++ b/compiler/rustc_attr_parsing/src/lints.rs
@@ -43,12 +43,18 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emi
                     ),
                 },
             ),
-        AttributeLintKind::EmptyAttribute { first_span } => lint_emitter.emit_node_span_lint(
-            rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
-            *id,
-            *first_span,
-            session_diagnostics::EmptyAttributeList { attr_span: *first_span },
-        ),
+        AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => {
+            lint_emitter.emit_node_span_lint(
+                rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
+                *id,
+                *first_span,
+                session_diagnostics::EmptyAttributeList {
+                    attr_span: *first_span,
+                    attr_path: attr_path.clone(),
+                    valid_without_list: *valid_without_list,
+                },
+            )
+        }
         AttributeLintKind::InvalidTarget { name, target, applied, only } => lint_emitter
             .emit_node_span_lint(
                 // This check is here because `deprecated` had its own lint group and removing this would be a breaking change
diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
index 2c2b14c8a68..1194ac5872c 100644
--- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs
+++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
@@ -503,9 +503,12 @@ pub(crate) struct EmptyConfusables {
 
 #[derive(LintDiagnostic)]
 #[diag(attr_parsing_empty_attribute)]
+#[note]
 pub(crate) struct EmptyAttributeList {
     #[suggestion(code = "", applicability = "machine-applicable")]
     pub attr_span: Span,
+    pub attr_path: AttrPath,
+    pub valid_without_list: bool,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_hir/src/lints.rs b/compiler/rustc_hir/src/lints.rs
index b7a0a6a0c19..c9de6f6b5d5 100644
--- a/compiler/rustc_hir/src/lints.rs
+++ b/compiler/rustc_hir/src/lints.rs
@@ -31,6 +31,12 @@ pub struct AttributeLint<Id> {
 
 #[derive(Clone, Debug, HashStable_Generic)]
 pub enum AttributeLintKind {
+    /// Copy of `IllFormedAttributeInput`
+    /// specifically for the `invalid_macro_export_arguments` lint until that is removed,
+    /// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663>
+    InvalidMacroExportArguments {
+        suggestions: Vec<String>,
+    },
     UnusedDuplicate {
         this: Span,
         other: Span,
@@ -41,13 +47,8 @@ pub enum AttributeLintKind {
     },
     EmptyAttribute {
         first_span: Span,
-    },
-
-    /// Copy of `IllFormedAttributeInput`
-    /// specifically for the `invalid_macro_export_arguments` lint until that is removed,
-    /// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663>
-    InvalidMacroExportArguments {
-        suggestions: Vec<String>,
+        attr_path: AttrPath,
+        valid_without_list: bool,
     },
     InvalidTarget {
         name: AttrPath,