about summary refs log tree commit diff
diff options
context:
space:
mode:
authorzetanumbers <dariasukhonina@gmail.com>2023-11-29 02:13:58 -0800
committerzetanumbers <dariasukhonina@gmail.com>2023-11-30 08:26:13 -0800
commitf7617c1cd4d1910613ffecdfd8de28889002f6cc (patch)
tree0e59cdec0aa2c45e9378af5cb273d7f37aabfa28
parent1670ff64bf1ccb2ad71068254b53725631c55864 (diff)
downloadrust-f7617c1cd4d1910613ffecdfd8de28889002f6cc.tar.gz
rust-f7617c1cd4d1910613ffecdfd8de28889002f6cc.zip
Enable link-arg link kind inside of #[link] attribute
- Implement link-arg as an attribute
- Apply suggestions from review
  - Co-authored-by: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
- Add unstable book entry
-rw-r--r--compiler/rustc_feature/src/unstable.rs3
-rw-r--r--compiler/rustc_metadata/messages.ftl2
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs12
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--src/doc/unstable-book/src/language-features/link-arg-attribute.md21
-rw-r--r--tests/run-make/pass-linker-flags-flavor/Makefile9
-rw-r--r--tests/run-make/pass-linker-flags-flavor/attribute.rs12
-rw-r--r--tests/run-make/pass-linker-flags-flavor/empty.rs (renamed from tests/run-make/pass-linker-flags-flavor/rs.rs)0
-rw-r--r--tests/run-make/pass-linker-flags-from-dep/Makefile6
-rw-r--r--tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs14
-rw-r--r--tests/run-make/pass-linker-flags-from-dep/rust_dep_flag.rs (renamed from tests/run-make/pass-linker-flags-from-dep/rust_dep.rs)0
-rw-r--r--tests/run-make/pass-linker-flags/Makefile3
-rw-r--r--tests/run-make/pass-linker-flags/attribute.rs11
-rw-r--r--tests/run-make/pass-linker-flags/empty.rs (renamed from tests/run-make/pass-linker-flags/rs.rs)0
-rw-r--r--tests/ui/error-codes/E0458.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-link-arg-attribute.rs5
-rw-r--r--tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr12
-rw-r--r--tests/ui/native-library-link-flags/link-arg-from-rs.rs9
-rw-r--r--tests/ui/native-library-link-flags/link-arg-from-rs.stderr18
19 files changed, 114 insertions, 26 deletions
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 8182c8779ff..87acb6f27c5 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -500,6 +500,9 @@ declare_features! (
     (incomplete, lazy_type_alias, "1.72.0", Some(112792), None),
     /// Allows `if/while p && let q = r && ...` chains.
     (unstable, let_chains, "1.37.0", Some(53667), None),
+    /// Allows using `#[link(kind = "link-arg", name = "...")]`
+    /// to pass custom arguments to the linker.
+    (unstable, link_arg_attribute, "CURRENT_RUSTC_VERSION", Some(99427), None),
     /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
     (unstable, lint_reasons, "1.31.0", Some(54503), None),
     /// Give access to additional metadata about declarative macro meta-variables.
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index 44b235a6d3d..8da6f0007f0 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -269,7 +269,7 @@ metadata_unknown_import_name_type =
     unknown import name type `{$import_name_type}`, expected one of: decorated, noprefix, undecorated
 
 metadata_unknown_link_kind =
-    unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib
+    unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib, link-arg
     .label = unknown link kind
 
 metadata_unknown_link_modifier =
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index f352fa6d46a..b3760b1099b 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -160,6 +160,18 @@ impl<'tcx> Collector<'tcx> {
                                 }
                                 NativeLibKind::RawDylib
                             }
+                            "link-arg" => {
+                                if !features.link_arg_attribute {
+                                    feature_err(
+                                        &sess.parse_sess,
+                                        sym::link_arg_attribute,
+                                        span,
+                                        "link kind `link-arg` is unstable",
+                                    )
+                                    .emit();
+                                }
+                                NativeLibKind::LinkArg
+                            }
                             kind => {
                                 sess.emit_err(errors::UnknownLinkKind { span, kind });
                                 continue;
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 46545416b5e..f1a1f23e6dd 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -934,6 +934,7 @@ symbols! {
         likely,
         line,
         link,
+        link_arg_attribute,
         link_args,
         link_cfg,
         link_llvm_intrinsics,
diff --git a/src/doc/unstable-book/src/language-features/link-arg-attribute.md b/src/doc/unstable-book/src/language-features/link-arg-attribute.md
new file mode 100644
index 00000000000..09915a7f274
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/link-arg-attribute.md
@@ -0,0 +1,21 @@
+# `link_arg_attribute`
+
+The tracking issue for this feature is: [#99427]
+
+------
+
+The `link_arg_attribute` feature allows passing arguments into the linker
+from inside of the source code. Order is preserved for link attributes as
+they were defined on a single extern block:
+
+```rust,no_run
+#![feature(link_arg_attribute)]
+
+#[link(kind = "link-arg", name = "--start-group")]
+#[link(kind = "static", name = "c")]
+#[link(kind = "static", name = "gcc")]
+#[link(kind = "link-arg", name = "--end-group")]
+extern "C" {}
+```
+
+[#99427]: https://github.com/rust-lang/rust/issues/99427
diff --git a/tests/run-make/pass-linker-flags-flavor/Makefile b/tests/run-make/pass-linker-flags-flavor/Makefile
index bd3d3ed882f..1bb05d0f974 100644
--- a/tests/run-make/pass-linker-flags-flavor/Makefile
+++ b/tests/run-make/pass-linker-flags-flavor/Makefile
@@ -3,6 +3,9 @@
 include ../tools.mk
 
 all:
-	$(RUSTC) rs.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3'
-	$(RUSTC) rs.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg:+verbatim=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3'
-	$(RUSTC) rs.rs -Z unstable-options -C linker-flavor=ld -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"'
+	$(RUSTC) empty.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3'
+	$(RUSTC) empty.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg:+verbatim=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3'
+	$(RUSTC) empty.rs -Z unstable-options -C linker-flavor=ld -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"'
+	$(RUSTC) attribute.rs -Z unstable-options -C linker-flavor=gnu-cc --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3'
+	$(RUSTC) --cfg 'feature="verbatim"' attribute.rs -Z unstable-options -C linker-flavor=gnu-cc --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3'
+	$(RUSTC) attribute.rs -C linker-flavor=ld --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"'
diff --git a/tests/run-make/pass-linker-flags-flavor/attribute.rs b/tests/run-make/pass-linker-flags-flavor/attribute.rs
new file mode 100644
index 00000000000..d099165301b
--- /dev/null
+++ b/tests/run-make/pass-linker-flags-flavor/attribute.rs
@@ -0,0 +1,12 @@
+#![feature(link_arg_attribute)]
+
+#[link(kind = "static", name = "l1")]
+#[cfg_attr(feature = "verbatim", link(kind = "link-arg", name = "a1", modifiers = "+verbatim"))]
+#[cfg_attr(not(feature = "verbatim"), link(kind = "link-arg", name = "a1"))]
+#[link(kind = "static", name = "l2")]
+#[link(kind = "link-arg", name = "a2")]
+#[link(kind = "dylib", name = "d1")]
+#[link(kind = "link-arg", name = "a3")]
+extern "C" {}
+
+fn main() {}
diff --git a/tests/run-make/pass-linker-flags-flavor/rs.rs b/tests/run-make/pass-linker-flags-flavor/empty.rs
index f328e4d9d04..f328e4d9d04 100644
--- a/tests/run-make/pass-linker-flags-flavor/rs.rs
+++ b/tests/run-make/pass-linker-flags-flavor/empty.rs
diff --git a/tests/run-make/pass-linker-flags-from-dep/Makefile b/tests/run-make/pass-linker-flags-from-dep/Makefile
index b57389bb7d4..48b3b26ce81 100644
--- a/tests/run-make/pass-linker-flags-from-dep/Makefile
+++ b/tests/run-make/pass-linker-flags-from-dep/Makefile
@@ -4,7 +4,9 @@ all:
 	# Build deps
 	$(RUSTC) native_dep_1.rs --crate-type=staticlib
 	$(RUSTC) native_dep_2.rs --crate-type=staticlib
-	$(RUSTC) rust_dep.rs -l static:-bundle=native_dep_1 -l link-arg=some_flag -l static:-bundle=native_dep_2 --crate-type=lib -Z unstable-options
+	$(RUSTC) rust_dep_flag.rs -l static:-bundle=native_dep_1 -l link-arg=some_flag -l static:-bundle=native_dep_2 --crate-type=lib -Z unstable-options
+	$(RUSTC) rust_dep_attr.rs --crate-type=lib
 
 	# Check sequence of linker args
-	$(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2'
+	$(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_flag.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2'
+	$(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_attr.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2'
diff --git a/tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs b/tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs
new file mode 100644
index 00000000000..ac5888ce610
--- /dev/null
+++ b/tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs
@@ -0,0 +1,14 @@
+#![feature(link_arg_attribute)]
+
+#[link(kind = "static", name = "native_dep_1", modifiers = "-bundle")]
+#[link(kind = "link-arg", name = "some_flag")]
+#[link(kind = "static", name = "native_dep_2", modifiers = "-bundle")]
+extern "C" {
+    pub fn foo();
+}
+
+pub fn f() {
+    unsafe {
+        foo();
+    }
+}
diff --git a/tests/run-make/pass-linker-flags-from-dep/rust_dep.rs b/tests/run-make/pass-linker-flags-from-dep/rust_dep_flag.rs
index 7f5df113934..7f5df113934 100644
--- a/tests/run-make/pass-linker-flags-from-dep/rust_dep.rs
+++ b/tests/run-make/pass-linker-flags-from-dep/rust_dep_flag.rs
diff --git a/tests/run-make/pass-linker-flags/Makefile b/tests/run-make/pass-linker-flags/Makefile
index 6ddbcbb1b08..226943e93bd 100644
--- a/tests/run-make/pass-linker-flags/Makefile
+++ b/tests/run-make/pass-linker-flags/Makefile
@@ -1,4 +1,5 @@
 include ../tools.mk
 
 all:
-	$(RUSTC) rs.rs -Z unstable-options -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3'
+	$(RUSTC) empty.rs -Z unstable-options -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3'
+	$(RUSTC) attribute.rs --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3'
diff --git a/tests/run-make/pass-linker-flags/attribute.rs b/tests/run-make/pass-linker-flags/attribute.rs
new file mode 100644
index 00000000000..6f784c01ff2
--- /dev/null
+++ b/tests/run-make/pass-linker-flags/attribute.rs
@@ -0,0 +1,11 @@
+#![feature(link_arg_attribute)]
+
+#[link(kind = "static", name = "l1")]
+#[link(kind = "link-arg", name = "a1")]
+#[link(kind = "static", name = "l2")]
+#[link(kind = "link-arg", name = "a2")]
+#[link(kind = "dylib", name = "d1")]
+#[link(kind = "link-arg", name = "a3")]
+extern "C" {}
+
+fn main() {}
diff --git a/tests/run-make/pass-linker-flags/rs.rs b/tests/run-make/pass-linker-flags/empty.rs
index f328e4d9d04..f328e4d9d04 100644
--- a/tests/run-make/pass-linker-flags/rs.rs
+++ b/tests/run-make/pass-linker-flags/empty.rs
diff --git a/tests/ui/error-codes/E0458.stderr b/tests/ui/error-codes/E0458.stderr
index e641bba541e..c13ae4e7862 100644
--- a/tests/ui/error-codes/E0458.stderr
+++ b/tests/ui/error-codes/E0458.stderr
@@ -1,4 +1,4 @@
-error[E0458]: unknown link kind `wonderful_unicorn`, expected one of: static, dylib, framework, raw-dylib
+error[E0458]: unknown link kind `wonderful_unicorn`, expected one of: static, dylib, framework, raw-dylib, link-arg
   --> $DIR/E0458.rs:1:15
    |
 LL | #[link(kind = "wonderful_unicorn")] extern "C" {}
diff --git a/tests/ui/feature-gates/feature-gate-link-arg-attribute.rs b/tests/ui/feature-gates/feature-gate-link-arg-attribute.rs
new file mode 100644
index 00000000000..9036095fbc4
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-link-arg-attribute.rs
@@ -0,0 +1,5 @@
+#[link(kind = "link-arg", name = "foo")]
+//~^ ERROR link kind `link-arg` is unstable
+extern "C" {}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr b/tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr
new file mode 100644
index 00000000000..673835b8b9e
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr
@@ -0,0 +1,12 @@
+error[E0658]: link kind `link-arg` is unstable
+  --> $DIR/feature-gate-link-arg-attribute.rs:1:15
+   |
+LL | #[link(kind = "link-arg", name = "foo")]
+   |               ^^^^^^^^^^
+   |
+   = note: see issue #99427 <https://github.com/rust-lang/rust/issues/99427> for more information
+   = help: add `#![feature(link_arg_attribute)]` to the crate attributes to enable
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/native-library-link-flags/link-arg-from-rs.rs b/tests/ui/native-library-link-flags/link-arg-from-rs.rs
index 075e4d9e79e..4a6017fea33 100644
--- a/tests/ui/native-library-link-flags/link-arg-from-rs.rs
+++ b/tests/ui/native-library-link-flags/link-arg-from-rs.rs
@@ -1,8 +1,7 @@
-// link-arg is not supposed to be usable in #[link] attributes
+#![feature(link_arg_attribute)]
 
-// compile-flags:
-// error-pattern: error[E0458]: unknown link kind `link-arg`, expected one of: static, dylib, framework, raw-dylib
-
-#[link(kind = "link-arg")]
+#[link(kind = "link-arg", name = "arg", modifiers = "+bundle")]
+//~^ ERROR linking modifier `bundle` is only compatible with `static` linking kind
 extern "C" {}
+
 pub fn main() {}
diff --git a/tests/ui/native-library-link-flags/link-arg-from-rs.stderr b/tests/ui/native-library-link-flags/link-arg-from-rs.stderr
index 69a7825c0b1..f31e15f1da6 100644
--- a/tests/ui/native-library-link-flags/link-arg-from-rs.stderr
+++ b/tests/ui/native-library-link-flags/link-arg-from-rs.stderr
@@ -1,16 +1,8 @@
-error[E0458]: unknown link kind `link-arg`, expected one of: static, dylib, framework, raw-dylib
-  --> $DIR/link-arg-from-rs.rs:6:15
+error: linking modifier `bundle` is only compatible with `static` linking kind
+  --> $DIR/link-arg-from-rs.rs:3:53
    |
-LL | #[link(kind = "link-arg")]
-   |               ^^^^^^^^^^ unknown link kind
+LL | #[link(kind = "link-arg", name = "arg", modifiers = "+bundle")]
+   |                                                     ^^^^^^^^^
 
-error[E0459]: `#[link]` attribute requires a `name = "string"` argument
-  --> $DIR/link-arg-from-rs.rs:6:1
-   |
-LL | #[link(kind = "link-arg")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `name` argument
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0458, E0459.
-For more information about an error, try `rustc --explain E0458`.