about summary refs log tree commit diff
diff options
context:
space:
mode:
authorcynecx <me@cynecx.net>2022-02-08 23:51:17 +0100
committercynecx <me@cynecx.net>2022-02-08 23:51:17 +0100
commit438826fd1a9a119d00992ede948cdd479431ecbb (patch)
treec7477627b59fff475ee3641e012f52d845daea82
parente075586d4fd428374a788eecc391e23ec4a17b46 (diff)
downloadrust-438826fd1a9a119d00992ede948cdd479431ecbb.tar.gz
rust-438826fd1a9a119d00992ede948cdd479431ecbb.zip
add more tests and make used(linker/compiler) mutually exclusive
-rw-r--r--compiler/rustc_passes/src/check_attr.rs34
-rw-r--r--compiler/rustc_typeck/src/collect.rs1
-rw-r--r--src/test/codegen/used_with_arg.rs6
-rw-r--r--src/test/ui/used_with_arg.rs19
-rw-r--r--src/test/ui/used_with_arg.stderr18
-rw-r--r--src/test/ui/used_with_multi_args.rs6
-rw-r--r--src/test/ui/used_with_multi_args.stderr8
7 files changed, 88 insertions, 4 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index ca511f7b814..479a08e43c0 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1741,12 +1741,46 @@ impl CheckAttrVisitor<'_> {
     }
 
     fn check_used(&self, attrs: &[Attribute], target: Target) {
+        let mut used_linker_span = None;
+        let mut used_compiler_span = None;
         for attr in attrs {
             if attr.has_name(sym::used) && target != Target::Static {
                 self.tcx
                     .sess
                     .span_err(attr.span, "attribute must be applied to a `static` variable");
             }
+            let inner = attr.meta_item_list();
+            match inner.as_deref() {
+                Some([item]) if item.has_name(sym::linker) => {
+                    if used_linker_span.is_none() {
+                        used_linker_span = Some(attr.span);
+                    }
+                }
+                Some([item]) if item.has_name(sym::compiler) => {
+                    if used_compiler_span.is_none() {
+                        used_compiler_span = Some(attr.span);
+                    }
+                }
+                Some(_) => {
+                    // This error case is handled in rustc_typeck::collect.
+                }
+                None => {
+                    // Default case (compiler) when arg isn't defined.
+                    if used_compiler_span.is_none() {
+                        used_compiler_span = Some(attr.span);
+                    }
+                }
+            }
+        }
+        if let (Some(linker_span), Some(compiler_span)) = (used_linker_span, used_compiler_span) {
+            let spans = vec![linker_span, compiler_span];
+            self.tcx
+                .sess
+                .struct_span_err(
+                    spans,
+                    "`used(compiler)` and `used(linker)` can't be used together",
+                )
+                .emit();
         }
     }
 
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 4a3c477021c..2a280ff97e9 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -1,3 +1,4 @@
+// ignore-tidy-filelength
 //! "Collection" is the process of determining the type and other external
 //! details of each item in Rust. Collection is specifically concerned
 //! with *inter-procedural* things -- for example, for a function
diff --git a/src/test/codegen/used_with_arg.rs b/src/test/codegen/used_with_arg.rs
index cd759b167c0..5bff50a40d4 100644
--- a/src/test/codegen/used_with_arg.rs
+++ b/src/test/codegen/used_with_arg.rs
@@ -1,12 +1,10 @@
-// compile-flags: -O
-
 #![crate_type = "lib"]
 #![feature(used_with_arg)]
 
-// CHECK: @llvm.used = appending global [1 x i8*]
+// CHECK: @llvm.used = appending global [1 x i8*]{{.*}}USED_LINKER
 #[used(linker)]
 static mut USED_LINKER: [usize; 1] = [0];
 
-// CHECK-NEXT: @llvm.compiler.used = appending global [1 x i8*]
+// CHECK-NEXT: @llvm.compiler.used = appending global [1 x i8*]{{.*}}USED_COMPILER
 #[used(compiler)]
 static mut USED_COMPILER: [usize; 1] = [0];
diff --git a/src/test/ui/used_with_arg.rs b/src/test/ui/used_with_arg.rs
new file mode 100644
index 00000000000..ad80ff53f0e
--- /dev/null
+++ b/src/test/ui/used_with_arg.rs
@@ -0,0 +1,19 @@
+#![feature(used_with_arg)]
+
+#[used(linker)]
+static mut USED_LINKER: [usize; 1] = [0];
+
+#[used(compiler)]
+static mut USED_COMPILER: [usize; 1] = [0];
+
+#[used(compiler)] //~ ERROR `used(compiler)` and `used(linker)` can't be used together
+#[used(linker)]
+static mut USED_COMPILER_LINKER2: [usize; 1] = [0];
+
+#[used(compiler)] //~ ERROR `used(compiler)` and `used(linker)` can't be used together
+#[used(linker)]
+#[used(compiler)]
+#[used(linker)]
+static mut USED_COMPILER_LINKER3: [usize; 1] = [0];
+
+fn main() {}
diff --git a/src/test/ui/used_with_arg.stderr b/src/test/ui/used_with_arg.stderr
new file mode 100644
index 00000000000..440e5c4a5a0
--- /dev/null
+++ b/src/test/ui/used_with_arg.stderr
@@ -0,0 +1,18 @@
+error: `used(compiler)` and `used(linker)` can't be used together
+  --> $DIR/used_with_arg.rs:9:1
+   |
+LL | #[used(compiler)]
+   | ^^^^^^^^^^^^^^^^^
+LL | #[used(linker)]
+   | ^^^^^^^^^^^^^^^
+
+error: `used(compiler)` and `used(linker)` can't be used together
+  --> $DIR/used_with_arg.rs:13:1
+   |
+LL | #[used(compiler)]
+   | ^^^^^^^^^^^^^^^^^
+LL | #[used(linker)]
+   | ^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/used_with_multi_args.rs b/src/test/ui/used_with_multi_args.rs
new file mode 100644
index 00000000000..2e17fcfd7a4
--- /dev/null
+++ b/src/test/ui/used_with_multi_args.rs
@@ -0,0 +1,6 @@
+#![feature(used_with_arg)]
+
+#[used(compiler, linker)] //~ expected `used`, `used(compiler)` or `used(linker)`
+static mut USED_COMPILER_LINKER: [usize; 1] = [0];
+
+fn main() {}
diff --git a/src/test/ui/used_with_multi_args.stderr b/src/test/ui/used_with_multi_args.stderr
new file mode 100644
index 00000000000..c93aafcfc7c
--- /dev/null
+++ b/src/test/ui/used_with_multi_args.stderr
@@ -0,0 +1,8 @@
+error: expected `used`, `used(compiler)` or `used(linker)`
+  --> $DIR/used_with_multi_args.rs:3:1
+   |
+LL | #[used(compiler, linker)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+