about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-27 03:19:12 +0000
committerbors <bors@rust-lang.org>2022-08-27 03:19:12 +0000
commit9845f4c47e7062867c73b6bed8f1df273b56d5d7 (patch)
tree96c457490b4ae27638a3be40daa381fedf948f2a /src/test
parentbb8a08f011ce481adc62e45150b642d1f160bd78 (diff)
parentcc49c3e582ae2c597954fe877774d8bc32427dc3 (diff)
downloadrust-9845f4c47e7062867c73b6bed8f1df273b56d5d7.tar.gz
rust-9845f4c47e7062867c73b6bed8f1df273b56d5d7.zip
Auto merge of #100732 - dpaoliello:import_name_type, r=wesleywiser
Implementation of import_name_type

Fixes #96534 by implementing https://github.com/rust-lang/compiler-team/issues/525

Symbols that are exported or imported from a binary on 32bit x86 Windows can be named in four separate ways, corresponding to the [import name types](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-name-type) from the PE-COFF spec. The exporting and importing binaries must use the same name encoding, otherwise mismatches can lead to link failures due to "missing symbols" or to 0xc0000139 (`STATUS_ENTRYPOINT_NOT_FOUND`) errors when the executable/library is loaded. For details, see the comments on the raw-dylib feature's https://github.com/rust-lang/rust/issues/58713. To generate the correct import libraries for these DLLs, therefore, rustc must know the import name type for each `extern` function, and there is currently no way for users to provide this information.

This change adds a new `MetaNameValueStr` key to the `#[link]` attribute called `import_name_type`, and which accepts one of three values: `decorated`, `noprefix`, and `undecorated`.

A single DLL is likely to export all its functions using the same import type name, hence `import_name_type` is a parameter of `#[link]` rather than being its own attribute that is applied per-function. It is possible to have a single DLL that exports different functions using different import name types, but users could express such cases by providing multiple export blocks for the same DLL, each with a different import name type.

Note: there is a fourth import name type defined in the PE-COFF spec, `IMPORT_ORDINAL`. This case is already handled by the `#[link_ordinal]` attribute. While it could be merged into `import_type_name`, that would not make sense as `#[link_ordinal]` provides per-function information (namely the ordinal itself).

Design decisions (these match the MCP linked above):
* For GNU, `decorated` matches the PE Spec and MSVC rather than the default behavior of `dlltool` (i.e., there will be a leading `_` for `stdcall`).
* If `import_name_type` is not present, we will keep our current behavior of matching the environment (MSVC vs GNU) default for decorating.
* Using `import_name_type` on architectures other than 32bit x86 will result in an error.
* Using `import_name_type` with link kinds other than `"raw-dylib"` will result in an error.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/Makefile22
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/driver.rs79
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/extern.c65
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/extern.gnu.def18
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/extern.msvc.def18
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/output.txt12
-rw-r--r--src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs8
-rw-r--r--src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr21
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-early.stderr4
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-late.stderr4
-rw-r--r--src/test/ui/malformed/malformed-regressions.stderr4
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs10
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr17
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs11
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr17
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs10
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr17
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs18
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr23
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.rs9
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.stderr17
21 files changed, 398 insertions, 6 deletions
diff --git a/src/test/run-make/raw-dylib-import-name-type/Makefile b/src/test/run-make/raw-dylib-import-name-type/Makefile
new file mode 100644
index 00000000000..fcc60e88e1a
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/Makefile
@@ -0,0 +1,22 @@
+# Test the behavior of #[link(.., kind = "raw-dylib")] with alternative calling conventions.
+
+# only-x86
+# only-windows
+
+-include ../../run-make-fulldeps/tools.mk
+
+all:
+	$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
+	$(call COMPILE_OBJ,"$(TMPDIR)"/extern.obj,extern.c)
+ifdef IS_MSVC
+	$(CC) "$(TMPDIR)"/extern.obj extern.msvc.def -link -dll -out:"$(TMPDIR)"/extern.dll -noimplib
+else
+	$(CC) "$(TMPDIR)"/extern.obj extern.gnu.def --no-leading-underscore -shared -o "$(TMPDIR)"/extern.dll
+endif
+	"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
+
+ifdef RUSTC_BLESS_TEST
+	cp "$(TMPDIR)"/output.txt output.txt
+else
+	$(DIFF) output.txt "$(TMPDIR)"/output.txt
+endif
diff --git a/src/test/run-make/raw-dylib-import-name-type/driver.rs b/src/test/run-make/raw-dylib-import-name-type/driver.rs
new file mode 100644
index 00000000000..74e9a89fbdf
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/driver.rs
@@ -0,0 +1,79 @@
+#![feature(raw_dylib)]
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
+extern "C" {
+    fn cdecl_fn_undecorated(i: i32);
+    static mut extern_variable_undecorated: i32;
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")]
+extern "C" {
+    fn cdecl_fn_noprefix(i: i32);
+    static mut extern_variable_noprefix: i32;
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "decorated")]
+extern "C" {
+    fn cdecl_fn_decorated(i: i32);
+    static mut extern_variable_decorated: i32;
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
+extern "stdcall" {
+    fn stdcall_fn_undecorated(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")]
+extern "stdcall" {
+    fn stdcall_fn_noprefix(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "decorated")]
+extern "stdcall" {
+    fn stdcall_fn_decorated(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
+extern "fastcall" {
+    fn fastcall_fn_undecorated(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")]
+extern "fastcall" {
+    fn fastcall_fn_noprefix(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib", import_name_type = "decorated")]
+extern "fastcall" {
+    fn fastcall_fn_decorated(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib")]
+extern {
+    fn print_extern_variable_undecorated();
+    fn print_extern_variable_noprefix();
+    fn print_extern_variable_decorated();
+}
+
+pub fn main() {
+    unsafe {
+        cdecl_fn_undecorated(1);
+        cdecl_fn_noprefix(2);
+        cdecl_fn_decorated(3);
+
+        stdcall_fn_undecorated(4);
+        stdcall_fn_noprefix(5);
+        stdcall_fn_decorated(6);
+
+        fastcall_fn_undecorated(7);
+        fastcall_fn_noprefix(8);
+        fastcall_fn_decorated(9);
+
+        extern_variable_undecorated = 42;
+        print_extern_variable_undecorated();
+        extern_variable_noprefix = 43;
+        print_extern_variable_noprefix();
+        extern_variable_decorated = 44;
+        print_extern_variable_decorated();
+    }
+}
diff --git a/src/test/run-make/raw-dylib-import-name-type/extern.c b/src/test/run-make/raw-dylib-import-name-type/extern.c
new file mode 100644
index 00000000000..1102158e249
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/extern.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void _cdecl cdecl_fn_undecorated(int i) {
+    printf("cdecl_fn_undecorated(%d)\n", i);
+    fflush(stdout);
+}
+
+void _cdecl cdecl_fn_noprefix(int i) {
+    printf("cdecl_fn_noprefix(%d)\n", i);
+    fflush(stdout);
+}
+
+void _cdecl cdecl_fn_decorated(int i) {
+    printf("cdecl_fn_decorated(%d)\n", i);
+    fflush(stdout);
+}
+
+void __stdcall stdcall_fn_undecorated(int i) {
+    printf("stdcall_fn_undecorated(%d)\n", i);
+    fflush(stdout);
+}
+
+void __stdcall stdcall_fn_noprefix(int i) {
+    printf("stdcall_fn_noprefix(%d)\n", i);
+    fflush(stdout);
+}
+
+void __stdcall stdcall_fn_decorated(int i) {
+    printf("stdcall_fn_decorated(%d)\n", i);
+    fflush(stdout);
+}
+
+void __fastcall fastcall_fn_undecorated(int i) {
+    printf("fastcall_fn_undecorated(%d)\n", i);
+    fflush(stdout);
+}
+
+void __fastcall fastcall_fn_noprefix(int i) {
+    printf("fastcall_fn_noprefix(%d)\n", i);
+    fflush(stdout);
+}
+
+void __fastcall fastcall_fn_decorated(int i) {
+    printf("fastcall_fn_decorated(%d)\n", i);
+    fflush(stdout);
+}
+
+int extern_variable_undecorated = 0;
+__declspec(dllexport) void print_extern_variable_undecorated() {
+    printf("extern_variable_undecorated value: %d\n", extern_variable_undecorated);
+    fflush(stdout);
+}
+
+int extern_variable_noprefix = 0;
+__declspec(dllexport) void print_extern_variable_noprefix() {
+    printf("extern_variable_noprefix value: %d\n", extern_variable_noprefix);
+    fflush(stdout);
+}
+
+int extern_variable_decorated = 0;
+__declspec(dllexport) void print_extern_variable_decorated() {
+    printf("extern_variable_decorated value: %d\n", extern_variable_decorated);
+    fflush(stdout);
+}
diff --git a/src/test/run-make/raw-dylib-import-name-type/extern.gnu.def b/src/test/run-make/raw-dylib-import-name-type/extern.gnu.def
new file mode 100644
index 00000000000..f06ce67e030
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/extern.gnu.def
@@ -0,0 +1,18 @@
+LIBRARY extern
+EXPORTS
+    cdecl_fn_undecorated
+    cdecl_fn_noprefix
+    cdecl_fn_decorated
+    stdcall_fn_undecorated
+    stdcall_fn_noprefix@4
+    fastcall_fn_undecorated
+    @fastcall_fn_decorated@4
+
+    ;ld doesn't handle fully-decorated stdcall, or no-prefix fastcall
+    _stdcall_fn_decorated@4=stdcall_fn_decorated@4
+    fastcall_fn_noprefix@4=@fastcall_fn_noprefix@4
+
+    ;Variables are never decorated
+    extern_variable_undecorated
+    extern_variable_noprefix
+    extern_variable_decorated
diff --git a/src/test/run-make/raw-dylib-import-name-type/extern.msvc.def b/src/test/run-make/raw-dylib-import-name-type/extern.msvc.def
new file mode 100644
index 00000000000..9dc333707cb
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/extern.msvc.def
@@ -0,0 +1,18 @@
+LIBRARY extern
+EXPORTS
+    cdecl_fn_undecorated
+    cdecl_fn_noprefix
+    cdecl_fn_decorated
+    stdcall_fn_undecorated
+    _stdcall_fn_decorated@4
+    fastcall_fn_undecorated
+    @fastcall_fn_decorated@4
+
+    ;MSVC doesn't seem to recognize the "no prefix" syntax.
+    stdcall_fn_noprefix@4=_stdcall_fn_noprefix@4
+    fastcall_fn_noprefix@4=@fastcall_fn_noprefix@4
+
+    ;Variables are never decorated
+    extern_variable_undecorated
+    extern_variable_noprefix
+    extern_variable_decorated
diff --git a/src/test/run-make/raw-dylib-import-name-type/output.txt b/src/test/run-make/raw-dylib-import-name-type/output.txt
new file mode 100644
index 00000000000..855b20a8645
--- /dev/null
+++ b/src/test/run-make/raw-dylib-import-name-type/output.txt
@@ -0,0 +1,12 @@
+cdecl_fn_undecorated(1)
+cdecl_fn_noprefix(2)
+cdecl_fn_decorated(3)
+stdcall_fn_undecorated(4)
+stdcall_fn_noprefix(5)
+stdcall_fn_decorated(6)
+fastcall_fn_undecorated(7)
+fastcall_fn_noprefix(8)
+fastcall_fn_decorated(9)
+extern_variable_undecorated value: 42
+extern_variable_noprefix value: 43
+extern_variable_decorated value: 44
diff --git a/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs b/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs
new file mode 100644
index 00000000000..33655cf8bdc
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs
@@ -0,0 +1,8 @@
+// only-windows
+// only-x86
+#[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
+//~^ ERROR link kind `raw-dylib` is unstable
+//~| ERROR import name type is unstable
+extern "C" {}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr b/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr
new file mode 100644
index 00000000000..be82dd11926
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr
@@ -0,0 +1,21 @@
+error[E0658]: link kind `raw-dylib` is unstable
+  --> $DIR/feature-gate-raw-dylib-import-name-type.rs:3:29
+   |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
+   |                             ^^^^^^^^^^^
+   |
+   = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+   = help: add `#![feature(raw_dylib)]` to the crate attributes to enable
+
+error[E0658]: import name type is unstable
+  --> $DIR/feature-gate-raw-dylib-import-name-type.rs:3:61
+   |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
+   |                                                             ^^^^^^^^^^^
+   |
+   = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+   = help: add `#![feature(raw_dylib)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/linkage-attr/link-attr-validation-early.stderr b/src/test/ui/linkage-attr/link-attr-validation-early.stderr
index d36601ed0b4..903141e439d 100644
--- a/src/test/ui/linkage-attr/link-attr-validation-early.stderr
+++ b/src/test/ui/linkage-attr/link-attr-validation-early.stderr
@@ -1,4 +1,4 @@
-error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]`
   --> $DIR/link-attr-validation-early.rs:2:1
    |
 LL | #[link]
@@ -8,7 +8,7 @@ LL | #[link]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]`
   --> $DIR/link-attr-validation-early.rs:4:1
    |
 LL | #[link = "foo"]
diff --git a/src/test/ui/linkage-attr/link-attr-validation-late.stderr b/src/test/ui/linkage-attr/link-attr-validation-late.stderr
index bb08f9a4c02..dd0f1dba2ec 100644
--- a/src/test/ui/linkage-attr/link-attr-validation-late.stderr
+++ b/src/test/ui/linkage-attr/link-attr-validation-late.stderr
@@ -1,10 +1,10 @@
-error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module
+error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
   --> $DIR/link-attr-validation-late.rs:5:22
    |
 LL | #[link(name = "...", "literal")]
    |                      ^^^^^^^^^
 
-error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module
+error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
   --> $DIR/link-attr-validation-late.rs:6:22
    |
 LL | #[link(name = "...", unknown)]
diff --git a/src/test/ui/malformed/malformed-regressions.stderr b/src/test/ui/malformed/malformed-regressions.stderr
index 13c12ff7213..8c2625bdf0d 100644
--- a/src/test/ui/malformed/malformed-regressions.stderr
+++ b/src/test/ui/malformed/malformed-regressions.stderr
@@ -26,7 +26,7 @@ LL | #[inline = ""]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]`
   --> $DIR/malformed-regressions.rs:7:1
    |
 LL | #[link]
@@ -35,7 +35,7 @@ LL | #[link]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]`
   --> $DIR/malformed-regressions.rs:9:1
    |
 LL | #[link = ""]
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs b/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs
new file mode 100644
index 00000000000..9e739c02dc8
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs
@@ -0,0 +1,10 @@
+// only-windows
+// only-x86
+#![feature(raw_dylib)]
+//~^ WARN the feature `raw_dylib` is incomplete
+
+#[link(name = "foo", kind = "raw-dylib", import_name_type = 6)]
+//~^ ERROR import name type must be of the form `import_name_type = "string"`
+extern "C" { }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr b/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr
new file mode 100644
index 00000000000..ee10b0114a4
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr
@@ -0,0 +1,17 @@
+warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/import-name-type-invalid-format.rs:3:12
+   |
+LL | #![feature(raw_dylib)]
+   |            ^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+
+error: import name type must be of the form `import_name_type = "string"`
+  --> $DIR/import-name-type-invalid-format.rs:6:42
+   |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)]
+   |                                          ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs b/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs
new file mode 100644
index 00000000000..c404dbae468
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs
@@ -0,0 +1,11 @@
+// ignore-tidy-linelength
+// only-windows
+// only-x86
+#![feature(raw_dylib)]
+//~^ WARN the feature `raw_dylib` is incomplete
+
+#[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")]
+//~^ ERROR multiple `import_name_type` arguments in a single `#[link]` attribute
+extern "C" { }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr b/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr
new file mode 100644
index 00000000000..936c8aa7359
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr
@@ -0,0 +1,17 @@
+warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/import-name-type-multiple.rs:4:12
+   |
+LL | #![feature(raw_dylib)]
+   |            ^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+
+error: multiple `import_name_type` arguments in a single `#[link]` attribute
+  --> $DIR/import-name-type-multiple.rs:7:74
+   |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")]
+   |                                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs
new file mode 100644
index 00000000000..350b0294641
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs
@@ -0,0 +1,10 @@
+// only-windows
+// only-x86
+#![feature(raw_dylib)]
+//~^ WARN the feature `raw_dylib` is incomplete
+
+#[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")]
+//~^ ERROR unknown import name type `unknown`, expected one of: decorated, noprefix, undecorated
+extern "C" { }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr
new file mode 100644
index 00000000000..b6871a0d317
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr
@@ -0,0 +1,17 @@
+warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/import-name-type-unknown-value.rs:3:12
+   |
+LL | #![feature(raw_dylib)]
+   |            ^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+
+error: unknown import name type `unknown`, expected one of: decorated, noprefix, undecorated
+  --> $DIR/import-name-type-unknown-value.rs:6:42
+   |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")]
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs
new file mode 100644
index 00000000000..b467917bacc
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs
@@ -0,0 +1,18 @@
+// only-windows
+// only-x86
+#![feature(raw_dylib)]
+//~^ WARN the feature `raw_dylib` is incomplete
+
+#[link(name = "foo", import_name_type = "decorated")]
+//~^ ERROR import name type can only be used with link kind `raw-dylib`
+extern "C" { }
+
+#[link(name = "bar", kind = "static", import_name_type = "decorated")]
+//~^ ERROR import name type can only be used with link kind `raw-dylib`
+extern "C" { }
+
+// Specifying `import_name_type` before `kind` shouldn't raise an error.
+#[link(name = "bar", import_name_type = "decorated", kind = "raw-dylib")]
+extern "C" { }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr
new file mode 100644
index 00000000000..c35333fb88d
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr
@@ -0,0 +1,23 @@
+warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/import-name-type-unsupported-link-kind.rs:3:12
+   |
+LL | #![feature(raw_dylib)]
+   |            ^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+
+error: import name type can only be used with link kind `raw-dylib`
+  --> $DIR/import-name-type-unsupported-link-kind.rs:6:22
+   |
+LL | #[link(name = "foo", import_name_type = "decorated")]
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: import name type can only be used with link kind `raw-dylib`
+  --> $DIR/import-name-type-unsupported-link-kind.rs:10:39
+   |
+LL | #[link(name = "bar", kind = "static", import_name_type = "decorated")]
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.rs b/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.rs
new file mode 100644
index 00000000000..4e6de7d6ac3
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.rs
@@ -0,0 +1,9 @@
+// only-windows
+// ignore-x86
+#![feature(raw_dylib)]
+//~^ WARN the feature `raw_dylib` is incomplete
+#[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
+//~^ ERROR import name type is only supported on x86
+extern "C" { }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.stderr b/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.stderr
new file mode 100644
index 00000000000..d8a585145a7
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/import-name-type-x86-only.stderr
@@ -0,0 +1,17 @@
+warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/import-name-type-x86-only.rs:3:12
+   |
+LL | #![feature(raw_dylib)]
+   |            ^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+
+error: import name type is only supported on x86
+  --> $DIR/import-name-type-x86-only.rs:5:42
+   |
+LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+