about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-08-17 18:18:18 +0200
committerGitHub <noreply@github.com>2024-08-17 18:18:18 +0200
commitcfeded47a4e54ee95f5fd52f70d3282989b0cc02 (patch)
tree8f12a46825c10b8b50e899a98d090056b45548d7
parentc6f81a452e291dd4ff5bcbc6ecb9cd6f2271f164 (diff)
parent3c8dad152bc1e3baca25e5b7b6b7ea6eccef060a (diff)
downloadrust-cfeded47a4e54ee95f5fd52f70d3282989b0cc02.tar.gz
rust-cfeded47a4e54ee95f5fd52f70d3282989b0cc02.zip
Rollup merge of #128989 - s7tya:check-linkage-attribute-pos, r=petrochenkov
Emit an error for invalid use of the linkage attribute

fixes #128486

Currently, the use of the linkage attribute for Mod, Impl,... is incorrectly permitted. This PR will correct this issue by generating errors, and I've also added some UI test cases for it.

Related: #128552.
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs15
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--tests/ui/attributes/linkage.rs42
-rw-r--r--tests/ui/attributes/linkage.stderr55
5 files changed, 124 insertions, 1 deletions
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 0318d34fb73..1ea4ca375f1 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -430,6 +430,10 @@ passes_link_section =
     .warn = {-passes_previously_accepted}
     .label = not a function or static
 
+passes_linkage =
+    attribute should be applied to a function or static
+    .label = not a function definition or static
+
 passes_macro_export =
     `#[macro_export]` only has an effect on macro definitions
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index bd157d1d619..a47add929eb 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -243,6 +243,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 [sym::coroutine, ..] => {
                     self.check_coroutine(attr, target);
                 }
+                [sym::linkage, ..] => self.check_linkage(attr, span, target),
                 [
                     // ok
                     sym::allow
@@ -256,7 +257,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     | sym::cfi_encoding // FIXME(cfi_encoding)
                     | sym::may_dangle // FIXME(dropck_eyepatch)
                     | sym::pointee // FIXME(derive_smart_pointer)
-                    | sym::linkage // FIXME(linkage)
                     | sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
                     | sym::used // handled elsewhere to restrict to static items
                     | sym::repr // handled elsewhere to restrict to type decls items
@@ -2347,6 +2347,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             }
         }
     }
+
+    fn check_linkage(&self, attr: &Attribute, span: Span, target: Target) {
+        match target {
+            Target::Fn
+            | Target::Method(..)
+            | Target::Static
+            | Target::ForeignStatic
+            | Target::ForeignFn => {}
+            _ => {
+                self.dcx().emit_err(errors::Linkage { attr_span: attr.span, span });
+            }
+        }
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 36dfc40e762..3a043e0e3c1 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -644,6 +644,15 @@ pub struct CoroutineOnNonClosure {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_linkage)]
+pub struct Linkage {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_empty_confusables)]
 pub(crate) struct EmptyConfusables {
     #[primary_span]
diff --git a/tests/ui/attributes/linkage.rs b/tests/ui/attributes/linkage.rs
new file mode 100644
index 00000000000..0d5ce699fa8
--- /dev/null
+++ b/tests/ui/attributes/linkage.rs
@@ -0,0 +1,42 @@
+#![feature(linkage)]
+#![feature(stmt_expr_attributes)]
+#![deny(unused_attributes)]
+#![allow(dead_code)]
+
+#[linkage = "weak"] //~ ERROR attribute should be applied to a function or static
+type InvalidTy = ();
+
+#[linkage = "weak"] //~ ERROR attribute should be applied to a function or static
+mod invalid_module {}
+
+#[linkage = "weak"] //~ ERROR attribute should be applied to a function or static
+struct F;
+
+#[linkage = "weak"] //~ ERROR attribute should be applied to a function or static
+impl F {
+    #[linkage = "weak"]
+    fn valid(&self) {}
+}
+
+#[linkage = "weak"]
+fn f() {
+    #[linkage = "weak"]
+    {
+        1
+    };
+    //~^^^^ ERROR attribute should be applied to a function or static
+}
+
+extern "C" {
+    #[linkage = "weak"]
+    static A: *const ();
+
+    #[linkage = "weak"]
+    fn bar();
+}
+
+fn main() {
+    let _ = #[linkage = "weak"]
+    (|| 1);
+    //~^^ ERROR attribute should be applied to a function or static
+}
diff --git a/tests/ui/attributes/linkage.stderr b/tests/ui/attributes/linkage.stderr
new file mode 100644
index 00000000000..d5595529f40
--- /dev/null
+++ b/tests/ui/attributes/linkage.stderr
@@ -0,0 +1,55 @@
+error: attribute should be applied to a function or static
+  --> $DIR/linkage.rs:6:1
+   |
+LL | #[linkage = "weak"]
+   | ^^^^^^^^^^^^^^^^^^^
+LL | type InvalidTy = ();
+   | -------------------- not a function definition or static
+
+error: attribute should be applied to a function or static
+  --> $DIR/linkage.rs:9:1
+   |
+LL | #[linkage = "weak"]
+   | ^^^^^^^^^^^^^^^^^^^
+LL | mod invalid_module {}
+   | --------------------- not a function definition or static
+
+error: attribute should be applied to a function or static
+  --> $DIR/linkage.rs:12:1
+   |
+LL | #[linkage = "weak"]
+   | ^^^^^^^^^^^^^^^^^^^
+LL | struct F;
+   | --------- not a function definition or static
+
+error: attribute should be applied to a function or static
+  --> $DIR/linkage.rs:15:1
+   |
+LL |   #[linkage = "weak"]
+   |   ^^^^^^^^^^^^^^^^^^^
+LL | / impl F {
+LL | |     #[linkage = "weak"]
+LL | |     fn valid(&self) {}
+LL | | }
+   | |_- not a function definition or static
+
+error: attribute should be applied to a function or static
+  --> $DIR/linkage.rs:23:5
+   |
+LL |       #[linkage = "weak"]
+   |       ^^^^^^^^^^^^^^^^^^^
+LL | /     {
+LL | |         1
+LL | |     };
+   | |_____- not a function definition or static
+
+error: attribute should be applied to a function or static
+  --> $DIR/linkage.rs:39:13
+   |
+LL |     let _ = #[linkage = "weak"]
+   |             ^^^^^^^^^^^^^^^^^^^
+LL |     (|| 1);
+   |     ------ not a function definition or static
+
+error: aborting due to 6 previous errors
+