about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2021-04-01 16:08:29 -0700
committerAlex Crichton <alex@alexcrichton.com>2021-04-08 08:03:18 -0700
commit482a3d06c3d1f83761bf3c94e1bad4fac7d32db4 (patch)
tree3071c93ffc1591f72b55b883fe639d21d94c6a82 /src/test
parent69e1d22ddbc67b25141a735a22a8895a678b32ca (diff)
downloadrust-482a3d06c3d1f83761bf3c94e1bad4fac7d32db4.tar.gz
rust-482a3d06c3d1f83761bf3c94e1bad4fac7d32db4.zip
rustc: Add a new `wasm` ABI
This commit implements the idea of a new ABI for the WebAssembly target,
one called `"wasm"`. This ABI is entirely of my own invention
and has no current precedent, but I think that the addition of this ABI
might help solve a number of issues with the WebAssembly targets.

When `wasm32-unknown-unknown` was first added to Rust I naively
"implemented an abi" for the target. I then went to write `wasm-bindgen`
which accidentally relied on details of this ABI. Turns out the ABI
definition didn't match C, which is causing issues for C/Rust interop.
Currently the compiler has a "wasm32 bindgen compat" ABI which is the
original implementation I added, and it's purely there for, well,
`wasm-bindgen`.

Another issue with the WebAssembly target is that it's not clear to me
when and if the default C ABI will change to account for WebAssembly's
multi-value feature (a feature that allows functions to return multiple
values). Even if this does happen, though, it seems like the C ABI will
be guided based on the performance of WebAssembly code and will likely
not match even what the current wasm-bindgen-compat ABI is today. This
leaves a hole in Rust's expressivity in binding WebAssembly where given
a particular import type, Rust may not be able to import that signature
with an updated C ABI for multi-value.

To fix these issues I had the idea of a new ABI for WebAssembly, one
called `wasm`. The definition of this ABI is "what you write
maps straight to wasm". The goal here is that whatever you write down in
the parameter list or in the return values goes straight into the
function's signature in the WebAssembly file. This special ABI is for
intentionally matching the ABI of an imported function from the
environment or exporting a function with the right signature.

With the addition of a new ABI, this enables rustc to:

* Eventually remove the "wasm-bindgen compat hack". Once this
  ABI is stable wasm-bindgen can switch to using it everywhere.
  Afterwards the wasm32-unknown-unknown target can have its default ABI
  updated to match C.

* Expose the ability to precisely match an ABI signature for a
  WebAssembly function, regardless of what the C ABI that clang chooses
  turns out to be.

* Continue to evolve the definition of the default C ABI to match what
  clang does on all targets, since the purpose of that ABI will be
  explicitly matching C rather than generating particular function
  imports/exports.

Naturally this is implemented as an unstable feature initially, but it
would be nice for this to get stabilized (if it works) in the near-ish
future to remove the wasm32-unknown-unknown incompatibility with the C
ABI. Doing this, however, requires the feature to be on stable because
wasm-bindgen works with stable Rust.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/run-make/wasm-abi/Makefile7
-rw-r--r--src/test/run-make/wasm-abi/foo.js22
-rw-r--r--src/test/run-make/wasm-abi/foo.rs87
-rw-r--r--src/test/ui/codemap_tests/unicode.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi.rs25
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi.stderr195
-rw-r--r--src/test/ui/feature-gates/feature-gate-wasm_abi.rs7
-rw-r--r--src/test/ui/feature-gates/feature-gate-wasm_abi.stderr12
-rw-r--r--src/test/ui/parser/issue-8537.stderr2
9 files changed, 282 insertions, 77 deletions
diff --git a/src/test/run-make/wasm-abi/Makefile b/src/test/run-make/wasm-abi/Makefile
new file mode 100644
index 00000000000..61fc4e8f57f
--- /dev/null
+++ b/src/test/run-make/wasm-abi/Makefile
@@ -0,0 +1,7 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# only-wasm32-bare
+
+all:
+	$(RUSTC) foo.rs --target wasm32-unknown-unknown
+	$(NODE) foo.js $(TMPDIR)/foo.wasm
diff --git a/src/test/run-make/wasm-abi/foo.js b/src/test/run-make/wasm-abi/foo.js
new file mode 100644
index 00000000000..9e9a65401af
--- /dev/null
+++ b/src/test/run-make/wasm-abi/foo.js
@@ -0,0 +1,22 @@
+const fs = require('fs');
+const process = require('process');
+const assert = require('assert');
+const buffer = fs.readFileSync(process.argv[2]);
+
+const m = new WebAssembly.Module(buffer);
+const i = new WebAssembly.Instance(m, {
+  host: {
+    two_i32: () => [100, 101],
+    two_i64: () => [102n, 103n],
+    two_f32: () => [104, 105],
+    two_f64: () => [106, 107],
+    mishmash: () => [108, 109, 110, 111n, 112, 113],
+  }
+});
+
+assert.deepEqual(i.exports.return_two_i32(), [1, 2])
+assert.deepEqual(i.exports.return_two_i64(), [3, 4])
+assert.deepEqual(i.exports.return_two_f32(), [5, 6])
+assert.deepEqual(i.exports.return_two_f64(), [7, 8])
+assert.deepEqual(i.exports.return_mishmash(), [9, 10, 11, 12, 13, 14])
+i.exports.call_imports();
diff --git a/src/test/run-make/wasm-abi/foo.rs b/src/test/run-make/wasm-abi/foo.rs
new file mode 100644
index 00000000000..0678eb3ff51
--- /dev/null
+++ b/src/test/run-make/wasm-abi/foo.rs
@@ -0,0 +1,87 @@
+#![crate_type = "cdylib"]
+#![deny(warnings)]
+#![feature(wasm_abi)]
+
+#[repr(C)]
+#[derive(PartialEq, Debug)]
+pub struct TwoI32 {
+    pub a: i32,
+    pub b: i32,
+}
+
+#[no_mangle]
+pub extern "wasm" fn return_two_i32() -> TwoI32 {
+    TwoI32 { a: 1, b: 2 }
+}
+
+#[repr(C)]
+#[derive(PartialEq, Debug)]
+pub struct TwoI64 {
+    pub a: i64,
+    pub b: i64,
+}
+
+#[no_mangle]
+pub extern "wasm" fn return_two_i64() -> TwoI64 {
+    TwoI64 { a: 3, b: 4 }
+}
+
+#[repr(C)]
+#[derive(PartialEq, Debug)]
+pub struct TwoF32 {
+    pub a: f32,
+    pub b: f32,
+}
+
+#[no_mangle]
+pub extern "wasm" fn return_two_f32() -> TwoF32 {
+    TwoF32 { a: 5., b: 6. }
+}
+
+#[repr(C)]
+#[derive(PartialEq, Debug)]
+pub struct TwoF64 {
+    pub a: f64,
+    pub b: f64,
+}
+
+#[no_mangle]
+pub extern "wasm" fn return_two_f64() -> TwoF64 {
+    TwoF64 { a: 7., b: 8. }
+}
+
+#[repr(C)]
+#[derive(PartialEq, Debug)]
+pub struct Mishmash {
+    pub a: f64,
+    pub b: f32,
+    pub c: i32,
+    pub d: i64,
+    pub e: TwoI32,
+}
+
+#[no_mangle]
+pub extern "wasm" fn return_mishmash() -> Mishmash {
+    Mishmash { a: 9., b: 10., c: 11, d: 12, e: TwoI32 { a: 13, b: 14 } }
+}
+
+#[link(wasm_import_module = "host")]
+extern "wasm" {
+    fn two_i32() -> TwoI32;
+    fn two_i64() -> TwoI64;
+    fn two_f32() -> TwoF32;
+    fn two_f64() -> TwoF64;
+    fn mishmash() -> Mishmash;
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn call_imports() {
+    assert_eq!(two_i32(), TwoI32 { a: 100, b: 101 });
+    assert_eq!(two_i64(), TwoI64 { a: 102, b: 103 });
+    assert_eq!(two_f32(), TwoF32 { a: 104., b: 105. });
+    assert_eq!(two_f64(), TwoF64 { a: 106., b: 107. });
+    assert_eq!(
+        mishmash(),
+        Mishmash { a: 108., b: 109., c: 110, d: 111, e: TwoI32 { a: 112, b: 113 } }
+    );
+}
diff --git a/src/test/ui/codemap_tests/unicode.stderr b/src/test/ui/codemap_tests/unicode.stderr
index b7ba4fa46d9..357dd25389e 100644
--- a/src/test/ui/codemap_tests/unicode.stderr
+++ b/src/test/ui/codemap_tests/unicode.stderr
@@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́`
 LL | extern "路濫狼á́́" fn foo() {}
    |        ^^^^^^^^^ invalid ABI
    |
-   = help: valid ABIs: Rust, C, C-unwind, cdecl, stdcall, stdcall-unwind, fastcall, vectorcall, thiscall, thiscall-unwind, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
+   = help: valid ABIs: Rust, C, C-unwind, cdecl, stdcall, stdcall-unwind, fastcall, vectorcall, thiscall, thiscall-unwind, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gates/feature-gate-abi.rs b/src/test/ui/feature-gates/feature-gate-abi.rs
index 3883106a3af..49cf2e158ed 100644
--- a/src/test/ui/feature-gates/feature-gate-abi.rs
+++ b/src/test/ui/feature-gates/feature-gate-abi.rs
@@ -10,9 +10,9 @@
 
 // Functions
 extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change
-//~^ ERROR intrinsic must be in
+                                   //~^ ERROR intrinsic must be in
 extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental
-//~^ ERROR intrinsic must be in
+                                       //~^ ERROR intrinsic must be in
 extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject to change
 extern "rust-call" fn f4(_: ()) {} //~ ERROR rust-call ABI is subject to change
 extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental
@@ -21,13 +21,14 @@ extern "x86-interrupt" fn f7() {} //~ ERROR x86-interrupt ABI is experimental
 extern "thiscall" fn f8() {} //~ ERROR thiscall is experimental and subject to change
 extern "amdgpu-kernel" fn f9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
 extern "efiapi" fn f10() {} //~ ERROR efiapi ABI is experimental and subject to change
+extern "wasm" fn f11() {} //~ ERROR wasm ABI is experimental and subject to change
 
 // Methods in trait definition
 trait Tr {
     extern "rust-intrinsic" fn m1(); //~ ERROR intrinsics are subject to change
-    //~^ ERROR intrinsic must be in
+                                     //~^ ERROR intrinsic must be in
     extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental
-    //~^ ERROR intrinsic must be in
+                                         //~^ ERROR intrinsic must be in
     extern "vectorcall" fn m3(); //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn m4(_: ()); //~ ERROR rust-call ABI is subject to change
     extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental
@@ -36,6 +37,7 @@ trait Tr {
     extern "thiscall" fn m8(); //~ ERROR thiscall is experimental and subject to change
     extern "amdgpu-kernel" fn m9(); //~ ERROR amdgpu-kernel ABI is experimental and subject to change
     extern "efiapi" fn m10(); //~ ERROR efiapi ABI is experimental and subject to change
+    extern "wasm" fn m11() {} //~ ERROR wasm ABI is experimental and subject to change
 
     extern "vectorcall" fn dm3() {} //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn dm4(_: ()) {} //~ ERROR rust-call ABI is subject to change
@@ -45,6 +47,7 @@ trait Tr {
     extern "thiscall" fn dm8() {} //~ ERROR thiscall is experimental and subject to change
     extern "amdgpu-kernel" fn dm9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
     extern "efiapi" fn dm10() {} //~ ERROR efiapi ABI is experimental and subject to change
+    extern "wasm" fn dm11() {} //~ ERROR wasm ABI is experimental and subject to change
 }
 
 struct S;
@@ -52,9 +55,9 @@ struct S;
 // Methods in trait impl
 impl Tr for S {
     extern "rust-intrinsic" fn m1() {} //~ ERROR intrinsics are subject to change
-    //~^ ERROR intrinsic must be in
+                                       //~^ ERROR intrinsic must be in
     extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental
-    //~^ ERROR intrinsic must be in
+                                           //~^ ERROR intrinsic must be in
     extern "vectorcall" fn m3() {} //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn m4(_: ()) {} //~ ERROR rust-call ABI is subject to change
     extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental
@@ -63,14 +66,15 @@ impl Tr for S {
     extern "thiscall" fn m8() {} //~ ERROR thiscall is experimental and subject to change
     extern "amdgpu-kernel" fn m9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
     extern "efiapi" fn m10() {} //~ ERROR efiapi ABI is experimental and subject to change
+    extern "wasm" fn m11() {} //~ ERROR wasm ABI is experimental and subject to change
 }
 
 // Methods in inherent impl
 impl S {
     extern "rust-intrinsic" fn im1() {} //~ ERROR intrinsics are subject to change
-    //~^ ERROR intrinsic must be in
+                                        //~^ ERROR intrinsic must be in
     extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental
-    //~^ ERROR intrinsic must be in
+                                            //~^ ERROR intrinsic must be in
     extern "vectorcall" fn im3() {} //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn im4(_: ()) {} //~ ERROR rust-call ABI is subject to change
     extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental
@@ -79,6 +83,7 @@ impl S {
     extern "thiscall" fn im8() {} //~ ERROR thiscall is experimental and subject to change
     extern "amdgpu-kernel" fn im9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
     extern "efiapi" fn im10() {} //~ ERROR efiapi ABI is experimental and subject to change
+    extern "wasm" fn im11() {} //~ ERROR wasm ABI is experimental and subject to change
 }
 
 // Function pointer types
@@ -87,11 +92,12 @@ type A2 = extern "platform-intrinsic" fn(); //~ ERROR platform intrinsics are ex
 type A3 = extern "vectorcall" fn(); //~ ERROR vectorcall is experimental and subject to change
 type A4 = extern "rust-call" fn(_: ()); //~ ERROR rust-call ABI is subject to change
 type A5 = extern "msp430-interrupt" fn(); //~ ERROR msp430-interrupt ABI is experimental
-type A6 = extern "ptx-kernel" fn (); //~ ERROR PTX ABIs are experimental and subject to change
+type A6 = extern "ptx-kernel" fn(); //~ ERROR PTX ABIs are experimental and subject to change
 type A7 = extern "x86-interrupt" fn(); //~ ERROR x86-interrupt ABI is experimental
 type A8 = extern "thiscall" fn(); //~ ERROR thiscall is experimental and subject to change
 type A9 = extern "amdgpu-kernel" fn(); //~ ERROR amdgpu-kernel ABI is experimental and subject to change
 type A10 = extern "efiapi" fn(); //~ ERROR efiapi ABI is experimental and subject to change
+type A11 = extern "wasm" fn(); //~ ERROR wasm ABI is experimental and subject to change
 
 // Foreign modules
 extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
@@ -104,5 +110,6 @@ extern "x86-interrupt" {} //~ ERROR x86-interrupt ABI is experimental
 extern "thiscall" {} //~ ERROR thiscall is experimental and subject to change
 extern "amdgpu-kernel" {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
 extern "efiapi" {} //~ ERROR efiapi ABI is experimental and subject to change
+extern "wasm" {} //~ ERROR wasm ABI is experimental and subject to change
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr
index eeeb349c662..078d21ad36f 100644
--- a/src/test/ui/feature-gates/feature-gate-abi.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi.stderr
@@ -85,8 +85,17 @@ LL | extern "efiapi" fn f10() {}
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi.rs:24:8
+   |
+LL | extern "wasm" fn f11() {}
+   |        ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:27:12
+  --> $DIR/feature-gate-abi.rs:28:12
    |
 LL |     extern "rust-intrinsic" fn m1();
    |            ^^^^^^^^^^^^^^^^
@@ -94,7 +103,7 @@ LL |     extern "rust-intrinsic" fn m1();
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:29:12
+  --> $DIR/feature-gate-abi.rs:30:12
    |
 LL |     extern "platform-intrinsic" fn m2();
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -103,7 +112,7 @@ LL |     extern "platform-intrinsic" fn m2();
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:31:12
+  --> $DIR/feature-gate-abi.rs:32:12
    |
 LL |     extern "vectorcall" fn m3();
    |            ^^^^^^^^^^^^
@@ -111,7 +120,7 @@ LL |     extern "vectorcall" fn m3();
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:32:12
+  --> $DIR/feature-gate-abi.rs:33:12
    |
 LL |     extern "rust-call" fn m4(_: ());
    |            ^^^^^^^^^^^
@@ -120,7 +129,7 @@ LL |     extern "rust-call" fn m4(_: ());
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:33:12
+  --> $DIR/feature-gate-abi.rs:34:12
    |
 LL |     extern "msp430-interrupt" fn m5();
    |            ^^^^^^^^^^^^^^^^^^
@@ -129,7 +138,7 @@ LL |     extern "msp430-interrupt" fn m5();
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:34:12
+  --> $DIR/feature-gate-abi.rs:35:12
    |
 LL |     extern "ptx-kernel" fn m6();
    |            ^^^^^^^^^^^^
@@ -138,7 +147,7 @@ LL |     extern "ptx-kernel" fn m6();
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:35:12
+  --> $DIR/feature-gate-abi.rs:36:12
    |
 LL |     extern "x86-interrupt" fn m7();
    |            ^^^^^^^^^^^^^^^
@@ -147,7 +156,7 @@ LL |     extern "x86-interrupt" fn m7();
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:36:12
+  --> $DIR/feature-gate-abi.rs:37:12
    |
 LL |     extern "thiscall" fn m8();
    |            ^^^^^^^^^^
@@ -155,7 +164,7 @@ LL |     extern "thiscall" fn m8();
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:37:12
+  --> $DIR/feature-gate-abi.rs:38:12
    |
 LL |     extern "amdgpu-kernel" fn m9();
    |            ^^^^^^^^^^^^^^^
@@ -164,7 +173,7 @@ LL |     extern "amdgpu-kernel" fn m9();
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:38:12
+  --> $DIR/feature-gate-abi.rs:39:12
    |
 LL |     extern "efiapi" fn m10();
    |            ^^^^^^^^
@@ -172,16 +181,25 @@ LL |     extern "efiapi" fn m10();
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
-error[E0658]: vectorcall is experimental and subject to change
+error[E0658]: wasm ABI is experimental and subject to change
   --> $DIR/feature-gate-abi.rs:40:12
    |
+LL |     extern "wasm" fn m11() {}
+   |            ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
+error[E0658]: vectorcall is experimental and subject to change
+  --> $DIR/feature-gate-abi.rs:42:12
+   |
 LL |     extern "vectorcall" fn dm3() {}
    |            ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:41:12
+  --> $DIR/feature-gate-abi.rs:43:12
    |
 LL |     extern "rust-call" fn dm4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -190,7 +208,7 @@ LL |     extern "rust-call" fn dm4(_: ()) {}
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:42:12
+  --> $DIR/feature-gate-abi.rs:44:12
    |
 LL |     extern "msp430-interrupt" fn dm5() {}
    |            ^^^^^^^^^^^^^^^^^^
@@ -199,7 +217,7 @@ LL |     extern "msp430-interrupt" fn dm5() {}
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:43:12
+  --> $DIR/feature-gate-abi.rs:45:12
    |
 LL |     extern "ptx-kernel" fn dm6() {}
    |            ^^^^^^^^^^^^
@@ -208,7 +226,7 @@ LL |     extern "ptx-kernel" fn dm6() {}
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:44:12
+  --> $DIR/feature-gate-abi.rs:46:12
    |
 LL |     extern "x86-interrupt" fn dm7() {}
    |            ^^^^^^^^^^^^^^^
@@ -217,7 +235,7 @@ LL |     extern "x86-interrupt" fn dm7() {}
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:45:12
+  --> $DIR/feature-gate-abi.rs:47:12
    |
 LL |     extern "thiscall" fn dm8() {}
    |            ^^^^^^^^^^
@@ -225,7 +243,7 @@ LL |     extern "thiscall" fn dm8() {}
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:46:12
+  --> $DIR/feature-gate-abi.rs:48:12
    |
 LL |     extern "amdgpu-kernel" fn dm9() {}
    |            ^^^^^^^^^^^^^^^
@@ -234,7 +252,7 @@ LL |     extern "amdgpu-kernel" fn dm9() {}
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:47:12
+  --> $DIR/feature-gate-abi.rs:49:12
    |
 LL |     extern "efiapi" fn dm10() {}
    |            ^^^^^^^^
@@ -242,8 +260,17 @@ LL |     extern "efiapi" fn dm10() {}
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi.rs:50:12
+   |
+LL |     extern "wasm" fn dm11() {}
+   |            ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:54:12
+  --> $DIR/feature-gate-abi.rs:57:12
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |            ^^^^^^^^^^^^^^^^
@@ -251,7 +278,7 @@ LL |     extern "rust-intrinsic" fn m1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:56:12
+  --> $DIR/feature-gate-abi.rs:59:12
    |
 LL |     extern "platform-intrinsic" fn m2() {}
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -260,7 +287,7 @@ LL |     extern "platform-intrinsic" fn m2() {}
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:58:12
+  --> $DIR/feature-gate-abi.rs:61:12
    |
 LL |     extern "vectorcall" fn m3() {}
    |            ^^^^^^^^^^^^
@@ -268,7 +295,7 @@ LL |     extern "vectorcall" fn m3() {}
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:59:12
+  --> $DIR/feature-gate-abi.rs:62:12
    |
 LL |     extern "rust-call" fn m4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -277,7 +304,7 @@ LL |     extern "rust-call" fn m4(_: ()) {}
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:60:12
+  --> $DIR/feature-gate-abi.rs:63:12
    |
 LL |     extern "msp430-interrupt" fn m5() {}
    |            ^^^^^^^^^^^^^^^^^^
@@ -286,7 +313,7 @@ LL |     extern "msp430-interrupt" fn m5() {}
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:61:12
+  --> $DIR/feature-gate-abi.rs:64:12
    |
 LL |     extern "ptx-kernel" fn m6() {}
    |            ^^^^^^^^^^^^
@@ -295,7 +322,7 @@ LL |     extern "ptx-kernel" fn m6() {}
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:62:12
+  --> $DIR/feature-gate-abi.rs:65:12
    |
 LL |     extern "x86-interrupt" fn m7() {}
    |            ^^^^^^^^^^^^^^^
@@ -304,7 +331,7 @@ LL |     extern "x86-interrupt" fn m7() {}
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:63:12
+  --> $DIR/feature-gate-abi.rs:66:12
    |
 LL |     extern "thiscall" fn m8() {}
    |            ^^^^^^^^^^
@@ -312,7 +339,7 @@ LL |     extern "thiscall" fn m8() {}
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:64:12
+  --> $DIR/feature-gate-abi.rs:67:12
    |
 LL |     extern "amdgpu-kernel" fn m9() {}
    |            ^^^^^^^^^^^^^^^
@@ -321,7 +348,7 @@ LL |     extern "amdgpu-kernel" fn m9() {}
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:65:12
+  --> $DIR/feature-gate-abi.rs:68:12
    |
 LL |     extern "efiapi" fn m10() {}
    |            ^^^^^^^^
@@ -329,8 +356,17 @@ LL |     extern "efiapi" fn m10() {}
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi.rs:69:12
+   |
+LL |     extern "wasm" fn m11() {}
+   |            ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:70:12
+  --> $DIR/feature-gate-abi.rs:74:12
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |            ^^^^^^^^^^^^^^^^
@@ -338,7 +374,7 @@ LL |     extern "rust-intrinsic" fn im1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:72:12
+  --> $DIR/feature-gate-abi.rs:76:12
    |
 LL |     extern "platform-intrinsic" fn im2() {}
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -347,7 +383,7 @@ LL |     extern "platform-intrinsic" fn im2() {}
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:74:12
+  --> $DIR/feature-gate-abi.rs:78:12
    |
 LL |     extern "vectorcall" fn im3() {}
    |            ^^^^^^^^^^^^
@@ -355,7 +391,7 @@ LL |     extern "vectorcall" fn im3() {}
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:75:12
+  --> $DIR/feature-gate-abi.rs:79:12
    |
 LL |     extern "rust-call" fn im4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -364,7 +400,7 @@ LL |     extern "rust-call" fn im4(_: ()) {}
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:76:12
+  --> $DIR/feature-gate-abi.rs:80:12
    |
 LL |     extern "msp430-interrupt" fn im5() {}
    |            ^^^^^^^^^^^^^^^^^^
@@ -373,7 +409,7 @@ LL |     extern "msp430-interrupt" fn im5() {}
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:77:12
+  --> $DIR/feature-gate-abi.rs:81:12
    |
 LL |     extern "ptx-kernel" fn im6() {}
    |            ^^^^^^^^^^^^
@@ -382,7 +418,7 @@ LL |     extern "ptx-kernel" fn im6() {}
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:78:12
+  --> $DIR/feature-gate-abi.rs:82:12
    |
 LL |     extern "x86-interrupt" fn im7() {}
    |            ^^^^^^^^^^^^^^^
@@ -391,7 +427,7 @@ LL |     extern "x86-interrupt" fn im7() {}
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:79:12
+  --> $DIR/feature-gate-abi.rs:83:12
    |
 LL |     extern "thiscall" fn im8() {}
    |            ^^^^^^^^^^
@@ -399,7 +435,7 @@ LL |     extern "thiscall" fn im8() {}
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:80:12
+  --> $DIR/feature-gate-abi.rs:84:12
    |
 LL |     extern "amdgpu-kernel" fn im9() {}
    |            ^^^^^^^^^^^^^^^
@@ -408,7 +444,7 @@ LL |     extern "amdgpu-kernel" fn im9() {}
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:81:12
+  --> $DIR/feature-gate-abi.rs:85:12
    |
 LL |     extern "efiapi" fn im10() {}
    |            ^^^^^^^^
@@ -416,8 +452,17 @@ LL |     extern "efiapi" fn im10() {}
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi.rs:86:12
+   |
+LL |     extern "wasm" fn im11() {}
+   |            ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:85:18
+  --> $DIR/feature-gate-abi.rs:90:18
    |
 LL | type A1 = extern "rust-intrinsic" fn();
    |                  ^^^^^^^^^^^^^^^^
@@ -425,7 +470,7 @@ LL | type A1 = extern "rust-intrinsic" fn();
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:86:18
+  --> $DIR/feature-gate-abi.rs:91:18
    |
 LL | type A2 = extern "platform-intrinsic" fn();
    |                  ^^^^^^^^^^^^^^^^^^^^
@@ -434,7 +479,7 @@ LL | type A2 = extern "platform-intrinsic" fn();
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:87:18
+  --> $DIR/feature-gate-abi.rs:92:18
    |
 LL | type A3 = extern "vectorcall" fn();
    |                  ^^^^^^^^^^^^
@@ -442,7 +487,7 @@ LL | type A3 = extern "vectorcall" fn();
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:88:18
+  --> $DIR/feature-gate-abi.rs:93:18
    |
 LL | type A4 = extern "rust-call" fn(_: ());
    |                  ^^^^^^^^^^^
@@ -451,7 +496,7 @@ LL | type A4 = extern "rust-call" fn(_: ());
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:89:18
+  --> $DIR/feature-gate-abi.rs:94:18
    |
 LL | type A5 = extern "msp430-interrupt" fn();
    |                  ^^^^^^^^^^^^^^^^^^
@@ -460,16 +505,16 @@ LL | type A5 = extern "msp430-interrupt" fn();
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:90:18
+  --> $DIR/feature-gate-abi.rs:95:18
    |
-LL | type A6 = extern "ptx-kernel" fn ();
+LL | type A6 = extern "ptx-kernel" fn();
    |                  ^^^^^^^^^^^^
    |
    = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:91:18
+  --> $DIR/feature-gate-abi.rs:96:18
    |
 LL | type A7 = extern "x86-interrupt" fn();
    |                  ^^^^^^^^^^^^^^^
@@ -478,7 +523,7 @@ LL | type A7 = extern "x86-interrupt" fn();
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:92:18
+  --> $DIR/feature-gate-abi.rs:97:18
    |
 LL | type A8 = extern "thiscall" fn();
    |                  ^^^^^^^^^^
@@ -486,7 +531,7 @@ LL | type A8 = extern "thiscall" fn();
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:93:18
+  --> $DIR/feature-gate-abi.rs:98:18
    |
 LL | type A9 = extern "amdgpu-kernel" fn();
    |                  ^^^^^^^^^^^^^^^
@@ -495,7 +540,7 @@ LL | type A9 = extern "amdgpu-kernel" fn();
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:94:19
+  --> $DIR/feature-gate-abi.rs:99:19
    |
 LL | type A10 = extern "efiapi" fn();
    |                   ^^^^^^^^
@@ -503,8 +548,17 @@ LL | type A10 = extern "efiapi" fn();
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi.rs:100:19
+   |
+LL | type A11 = extern "wasm" fn();
+   |                   ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:97:8
+  --> $DIR/feature-gate-abi.rs:103:8
    |
 LL | extern "rust-intrinsic" {}
    |        ^^^^^^^^^^^^^^^^
@@ -512,7 +566,7 @@ LL | extern "rust-intrinsic" {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:98:8
+  --> $DIR/feature-gate-abi.rs:104:8
    |
 LL | extern "platform-intrinsic" {}
    |        ^^^^^^^^^^^^^^^^^^^^
@@ -521,7 +575,7 @@ LL | extern "platform-intrinsic" {}
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:99:8
+  --> $DIR/feature-gate-abi.rs:105:8
    |
 LL | extern "vectorcall" {}
    |        ^^^^^^^^^^^^
@@ -529,7 +583,7 @@ LL | extern "vectorcall" {}
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:100:8
+  --> $DIR/feature-gate-abi.rs:106:8
    |
 LL | extern "rust-call" {}
    |        ^^^^^^^^^^^
@@ -538,7 +592,7 @@ LL | extern "rust-call" {}
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:101:8
+  --> $DIR/feature-gate-abi.rs:107:8
    |
 LL | extern "msp430-interrupt" {}
    |        ^^^^^^^^^^^^^^^^^^
@@ -547,7 +601,7 @@ LL | extern "msp430-interrupt" {}
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:102:8
+  --> $DIR/feature-gate-abi.rs:108:8
    |
 LL | extern "ptx-kernel" {}
    |        ^^^^^^^^^^^^
@@ -556,7 +610,7 @@ LL | extern "ptx-kernel" {}
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:103:8
+  --> $DIR/feature-gate-abi.rs:109:8
    |
 LL | extern "x86-interrupt" {}
    |        ^^^^^^^^^^^^^^^
@@ -565,7 +619,7 @@ LL | extern "x86-interrupt" {}
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:104:8
+  --> $DIR/feature-gate-abi.rs:110:8
    |
 LL | extern "thiscall" {}
    |        ^^^^^^^^^^
@@ -573,7 +627,7 @@ LL | extern "thiscall" {}
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:105:8
+  --> $DIR/feature-gate-abi.rs:111:8
    |
 LL | extern "amdgpu-kernel" {}
    |        ^^^^^^^^^^^^^^^
@@ -582,7 +636,7 @@ LL | extern "amdgpu-kernel" {}
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:106:8
+  --> $DIR/feature-gate-abi.rs:112:8
    |
 LL | extern "efiapi" {}
    |        ^^^^^^^^
@@ -590,14 +644,23 @@ LL | extern "efiapi" {}
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi.rs:113:8
+   |
+LL | extern "wasm" {}
+   |        ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:27:32
+  --> $DIR/feature-gate-abi.rs:28:32
    |
 LL |     extern "rust-intrinsic" fn m1();
    |                                ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:29:36
+  --> $DIR/feature-gate-abi.rs:30:36
    |
 LL |     extern "platform-intrinsic" fn m2();
    |                                    ^^
@@ -615,29 +678,29 @@ LL | extern "platform-intrinsic" fn f2() {}
    |                                     ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:54:37
+  --> $DIR/feature-gate-abi.rs:57:37
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |                                     ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:56:41
+  --> $DIR/feature-gate-abi.rs:59:41
    |
 LL |     extern "platform-intrinsic" fn m2() {}
    |                                         ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:70:38
+  --> $DIR/feature-gate-abi.rs:74:38
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |                                      ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:72:42
+  --> $DIR/feature-gate-abi.rs:76:42
    |
 LL |     extern "platform-intrinsic" fn im2() {}
    |                                          ^^
 
-error: aborting due to 76 previous errors
+error: aborting due to 83 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-wasm_abi.rs b/src/test/ui/feature-gates/feature-gate-wasm_abi.rs
new file mode 100644
index 00000000000..8c8de076365
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-wasm_abi.rs
@@ -0,0 +1,7 @@
+extern "wasm" fn foo() {
+    //~^ ERROR: wasm ABI is experimental and subject to change
+}
+
+fn main() {
+    foo();
+}
diff --git a/src/test/ui/feature-gates/feature-gate-wasm_abi.stderr b/src/test/ui/feature-gates/feature-gate-wasm_abi.stderr
new file mode 100644
index 00000000000..c4113fd6af9
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-wasm_abi.stderr
@@ -0,0 +1,12 @@
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-wasm_abi.rs:1:8
+   |
+LL | extern "wasm" fn foo() {
+   |        ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/parser/issue-8537.stderr b/src/test/ui/parser/issue-8537.stderr
index 85e2b77d867..5a29ce2221f 100644
--- a/src/test/ui/parser/issue-8537.stderr
+++ b/src/test/ui/parser/issue-8537.stderr
@@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `invalid-ab_isize`
 LL |   "invalid-ab_isize"
    |   ^^^^^^^^^^^^^^^^^^ invalid ABI
    |
-   = help: valid ABIs: Rust, C, C-unwind, cdecl, stdcall, stdcall-unwind, fastcall, vectorcall, thiscall, thiscall-unwind, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
+   = help: valid ABIs: Rust, C, C-unwind, cdecl, stdcall, stdcall-unwind, fastcall, vectorcall, thiscall, thiscall-unwind, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
 
 error: aborting due to previous error