From 2df4f7dd8c51e1c3e65b615d1c44fdc9d0b4b044 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 2 May 2024 01:15:40 +0000
Subject: [PATCH 1/9] Suggest borrowing on fn argument that is `impl AsRef`

When encountering a move conflict, on an expression that is `!Copy` passed as an argument to an `fn` that is `impl AsRef`, suggest borrowing the expression.

```
error[E0382]: use of moved value: `bar`
  --> f204.rs:14:15
   |
12 |     let bar = Bar;
   |         --- move occurs because `bar` has type `Bar`, which does not implement the `Copy` trait
13 |     foo(bar);
   |         --- value moved here
14 |     let baa = bar;
   |               ^^^ value used here after move
   |
help: borrow the value to avoid moving it
   |
13 |     foo(&bar);
   |         +
```

Fix #41708
---
 .../src/diagnostics/conflict_errors.rs        | 89 +++++++++++++++----
 library/core/src/borrow.rs                    |  1 +
 .../ui/moves/moved-value-on-as-ref-arg.fixed  | 37 ++++++++
 tests/ui/moves/moved-value-on-as-ref-arg.rs   | 37 ++++++++
 .../ui/moves/moved-value-on-as-ref-arg.stderr | 79 ++++++++++++++++
 5 files changed, 224 insertions(+), 19 deletions(-)
 create mode 100644 tests/ui/moves/moved-value-on-as-ref-arg.fixed
 create mode 100644 tests/ui/moves/moved-value-on-as-ref-arg.rs
 create mode 100644 tests/ui/moves/moved-value-on-as-ref-arg.stderr

diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 6f0bd0543293c..9efb3362e18ee 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -449,6 +449,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 } else {
                     (None, &[][..], 0)
                 };
+                let mut can_suggest_clone = true;
                 if let Some(def_id) = def_id
                     && let node = self.infcx.tcx.hir_node_by_def_id(def_id)
                     && let Some(fn_sig) = node.fn_sig()
@@ -456,24 +457,73 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     && let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
                     && let Some(arg) = fn_sig.decl.inputs.get(pos + offset)
                 {
-                    let mut span: MultiSpan = arg.span.into();
-                    span.push_span_label(
-                        arg.span,
-                        "this parameter takes ownership of the value".to_string(),
-                    );
-                    let descr = match node.fn_kind() {
-                        Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function",
-                        Some(hir::intravisit::FnKind::Method(..)) => "method",
-                        Some(hir::intravisit::FnKind::Closure) => "closure",
-                    };
-                    span.push_span_label(ident.span, format!("in this {descr}"));
-                    err.span_note(
-                        span,
-                        format!(
-                            "consider changing this parameter type in {descr} `{ident}` to borrow \
-                             instead if owning the value isn't necessary",
-                        ),
-                    );
+                    let mut is_mut = false;
+                    if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = arg.kind
+                        && let Res::Def(DefKind::TyParam, param_def_id) = path.res
+                        && self
+                            .infcx
+                            .tcx
+                            .predicates_of(def_id)
+                            .instantiate_identity(self.infcx.tcx)
+                            .predicates
+                            .into_iter()
+                            .any(|pred| {
+                                if let ty::ClauseKind::Trait(predicate) = pred.kind().skip_binder()
+                                    && [
+                                        self.infcx.tcx.get_diagnostic_item(sym::AsRef),
+                                        self.infcx.tcx.get_diagnostic_item(sym::AsMut),
+                                        self.infcx.tcx.get_diagnostic_item(sym::Borrow),
+                                        self.infcx.tcx.get_diagnostic_item(sym::BorrowMut),
+                                    ]
+                                    .contains(&Some(predicate.def_id()))
+                                    && let ty::Param(param) = predicate.self_ty().kind()
+                                    && let generics = self.infcx.tcx.generics_of(def_id)
+                                    && let param = generics.type_param(*param, self.infcx.tcx)
+                                    && param.def_id == param_def_id
+                                {
+                                    if [
+                                        self.infcx.tcx.get_diagnostic_item(sym::AsMut),
+                                        self.infcx.tcx.get_diagnostic_item(sym::BorrowMut),
+                                    ]
+                                    .contains(&Some(predicate.def_id()))
+                                    {
+                                        is_mut = true;
+                                    }
+                                    true
+                                } else {
+                                    false
+                                }
+                            })
+                    {
+                        // The type of the argument corresponding to the expression that got moved
+                        // is a type parameter `T`, which is has a `T: AsRef` obligation.
+                        err.span_suggestion_verbose(
+                            expr.span.shrink_to_lo(),
+                            "borrow the value to avoid moving it",
+                            format!("&{}", if is_mut { "mut " } else { "" }),
+                            Applicability::MachineApplicable,
+                        );
+                        can_suggest_clone = is_mut;
+                    } else {
+                        let mut span: MultiSpan = arg.span.into();
+                        span.push_span_label(
+                            arg.span,
+                            "this parameter takes ownership of the value".to_string(),
+                        );
+                        let descr = match node.fn_kind() {
+                            Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function",
+                            Some(hir::intravisit::FnKind::Method(..)) => "method",
+                            Some(hir::intravisit::FnKind::Closure) => "closure",
+                        };
+                        span.push_span_label(ident.span, format!("in this {descr}"));
+                        err.span_note(
+                            span,
+                            format!(
+                                "consider changing this parameter type in {descr} `{ident}` to \
+                                 borrow instead if owning the value isn't necessary",
+                            ),
+                        );
+                    }
                 }
                 let place = &self.move_data.move_paths[mpi].place;
                 let ty = place.ty(self.body, self.infcx.tcx).ty;
@@ -491,9 +541,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         ClosureKind::Coroutine(CoroutineKind::Desugared(_, CoroutineSource::Block)),
                     ..
                 } = move_spans
+                    && can_suggest_clone
                 {
                     self.suggest_cloning(err, ty, expr, None, Some(move_spans));
-                } else if self.suggest_hoisting_call_outside_loop(err, expr) {
+                } else if self.suggest_hoisting_call_outside_loop(err, expr) && can_suggest_clone {
                     // The place where the type moves would be misleading to suggest clone.
                     // #121466
                     self.suggest_cloning(err, ty, expr, None, Some(move_spans));
diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs
index bc026d0a44634..ccb1cc4e974d6 100644
--- a/library/core/src/borrow.rs
+++ b/library/core/src/borrow.rs
@@ -184,6 +184,7 @@ pub trait Borrow<Borrowed: ?Sized> {
 /// an underlying type by providing a mutable reference. See [`Borrow<T>`]
 /// for more information on borrowing as another type.
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_diagnostic_item = "BorrowMut"]
 pub trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> {
     /// Mutably borrows from an owned value.
     ///
diff --git a/tests/ui/moves/moved-value-on-as-ref-arg.fixed b/tests/ui/moves/moved-value-on-as-ref-arg.fixed
new file mode 100644
index 0000000000000..292fa98a3f71b
--- /dev/null
+++ b/tests/ui/moves/moved-value-on-as-ref-arg.fixed
@@ -0,0 +1,37 @@
+//@ run-rustfix
+#![allow(unused_mut)]
+use std::borrow::{Borrow, BorrowMut};
+use std::convert::{AsMut, AsRef};
+struct Bar;
+
+impl AsRef<Bar> for Bar {
+    fn as_ref(&self) -> &Bar {
+        self
+    }
+}
+
+impl AsMut<Bar> for Bar {
+    fn as_mut(&mut self) -> &mut Bar {
+        self
+    }
+}
+
+fn foo<T: AsRef<Bar>>(_: T) {}
+fn qux<T: AsMut<Bar>>(_: T) {}
+fn bat<T: Borrow<T>>(_: T) {}
+fn baz<T: BorrowMut<T>>(_: T) {}
+
+pub fn main() {
+    let bar = Bar;
+    foo(&bar);
+    let _baa = bar; //~ ERROR use of moved value
+    let mut bar = Bar;
+    qux(&mut bar);
+    let _baa = bar; //~ ERROR use of moved value
+    let bar = Bar;
+    bat(&bar);
+    let _baa = bar; //~ ERROR use of moved value
+    let mut bar = Bar;
+    baz(&mut bar);
+    let _baa = bar; //~ ERROR use of moved value
+}
diff --git a/tests/ui/moves/moved-value-on-as-ref-arg.rs b/tests/ui/moves/moved-value-on-as-ref-arg.rs
new file mode 100644
index 0000000000000..632af9efcda3e
--- /dev/null
+++ b/tests/ui/moves/moved-value-on-as-ref-arg.rs
@@ -0,0 +1,37 @@
+//@ run-rustfix
+#![allow(unused_mut)]
+use std::borrow::{Borrow, BorrowMut};
+use std::convert::{AsMut, AsRef};
+struct Bar;
+
+impl AsRef<Bar> for Bar {
+    fn as_ref(&self) -> &Bar {
+        self
+    }
+}
+
+impl AsMut<Bar> for Bar {
+    fn as_mut(&mut self) -> &mut Bar {
+        self
+    }
+}
+
+fn foo<T: AsRef<Bar>>(_: T) {}
+fn qux<T: AsMut<Bar>>(_: T) {}
+fn bat<T: Borrow<T>>(_: T) {}
+fn baz<T: BorrowMut<T>>(_: T) {}
+
+pub fn main() {
+    let bar = Bar;
+    foo(bar);
+    let _baa = bar; //~ ERROR use of moved value
+    let mut bar = Bar;
+    qux(bar);
+    let _baa = bar; //~ ERROR use of moved value
+    let bar = Bar;
+    bat(bar);
+    let _baa = bar; //~ ERROR use of moved value
+    let mut bar = Bar;
+    baz(bar);
+    let _baa = bar; //~ ERROR use of moved value
+}
diff --git a/tests/ui/moves/moved-value-on-as-ref-arg.stderr b/tests/ui/moves/moved-value-on-as-ref-arg.stderr
new file mode 100644
index 0000000000000..4004b7a43bc09
--- /dev/null
+++ b/tests/ui/moves/moved-value-on-as-ref-arg.stderr
@@ -0,0 +1,79 @@
+error[E0382]: use of moved value: `bar`
+  --> $DIR/moved-value-on-as-ref-arg.rs:27:16
+   |
+LL |     let bar = Bar;
+   |         --- move occurs because `bar` has type `Bar`, which does not implement the `Copy` trait
+LL |     foo(bar);
+   |         --- value moved here
+LL |     let _baa = bar;
+   |                ^^^ value used here after move
+   |
+help: borrow the value to avoid moving it
+   |
+LL |     foo(&bar);
+   |         +
+
+error[E0382]: use of moved value: `bar`
+  --> $DIR/moved-value-on-as-ref-arg.rs:30:16
+   |
+LL |     let mut bar = Bar;
+   |         ------- move occurs because `bar` has type `Bar`, which does not implement the `Copy` trait
+LL |     qux(bar);
+   |         --- value moved here
+LL |     let _baa = bar;
+   |                ^^^ value used here after move
+   |
+note: if `Bar` implemented `Clone`, you could clone the value
+  --> $DIR/moved-value-on-as-ref-arg.rs:5:1
+   |
+LL | struct Bar;
+   | ^^^^^^^^^^ consider implementing `Clone` for this type
+...
+LL |     qux(bar);
+   |         --- you could clone this value
+help: borrow the value to avoid moving it
+   |
+LL |     qux(&mut bar);
+   |         ++++
+
+error[E0382]: use of moved value: `bar`
+  --> $DIR/moved-value-on-as-ref-arg.rs:33:16
+   |
+LL |     let bar = Bar;
+   |         --- move occurs because `bar` has type `Bar`, which does not implement the `Copy` trait
+LL |     bat(bar);
+   |         --- value moved here
+LL |     let _baa = bar;
+   |                ^^^ value used here after move
+   |
+help: borrow the value to avoid moving it
+   |
+LL |     bat(&bar);
+   |         +
+
+error[E0382]: use of moved value: `bar`
+  --> $DIR/moved-value-on-as-ref-arg.rs:36:16
+   |
+LL |     let mut bar = Bar;
+   |         ------- move occurs because `bar` has type `Bar`, which does not implement the `Copy` trait
+LL |     baz(bar);
+   |         --- value moved here
+LL |     let _baa = bar;
+   |                ^^^ value used here after move
+   |
+note: if `Bar` implemented `Clone`, you could clone the value
+  --> $DIR/moved-value-on-as-ref-arg.rs:5:1
+   |
+LL | struct Bar;
+   | ^^^^^^^^^^ consider implementing `Clone` for this type
+...
+LL |     baz(bar);
+   |         --- you could clone this value
+help: borrow the value to avoid moving it
+   |
+LL |     baz(&mut bar);
+   |         ++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0382`.

From 45ad522e8745b9d2da00c56e93cca4d2f8c8fe7c Mon Sep 17 00:00:00 2001
From: Tobias Bucher <tobiasbucher5991@gmail.com>
Date: Wed, 10 Jul 2024 15:47:24 +0200
Subject: [PATCH 2/9] Don't mark `DEBUG_EVENT` struct as `repr(packed)`

That would give it alignment of 1 which is ABI-incompatible with its C
definition.
---
 library/std/src/process/tests.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs
index 63455a274faaa..b4f6bb71c79c4 100644
--- a/library/std/src/process/tests.rs
+++ b/library/std/src/process/tests.rs
@@ -386,7 +386,7 @@ fn test_interior_nul_in_env_value_is_error() {
 fn test_creation_flags() {
     use crate::os::windows::process::CommandExt;
     use crate::sys::c::{BOOL, DWORD, INFINITE};
-    #[repr(C, packed)]
+    #[repr(C)]
     struct DEBUG_EVENT {
         pub event_code: DWORD,
         pub process_id: DWORD,

From 00657639504230363d22b731ed15a2a80112a8b2 Mon Sep 17 00:00:00 2001
From: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Date: Wed, 10 Jul 2024 23:21:57 +0200
Subject: [PATCH 3/9] core: Limit remaining f16 doctests to x86_64 linux

On s390x, every use of the f16 data type will currently ICE
due to https://github.com/llvm/llvm-project/issues/50374,
causing doctest failures on the platform.

Most doctests were already restricted to certain platforms,
so fix this by likewise restricting the remaining five.
---
 library/core/src/num/f16.rs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index e74300d6c2f33..0e54d78231da8 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -353,12 +353,15 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
+    /// # // FIXME(f16_f128): LLVM crashes on s390x, llvm/llvm-project#50374
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let f = 7.0_f16;
     /// let g = -7.0_f16;
     ///
     /// assert!(f.is_sign_positive());
     /// assert!(!g.is_sign_positive());
+    /// # }
     /// ```
     #[inline]
     #[must_use]
@@ -376,12 +379,15 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
+    /// # // FIXME(f16_f128): LLVM crashes on s390x, llvm/llvm-project#50374
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let f = 7.0_f16;
     /// let g = -7.0_f16;
     ///
     /// assert!(!f.is_sign_negative());
     /// assert!(g.is_sign_negative());
+    /// # }
     /// ```
     #[inline]
     #[must_use]
@@ -694,9 +700,12 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
+    /// # // FIXME(f16_f128): LLVM crashes on s390x, llvm/llvm-project#50374
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let bytes = 12.5f16.to_be_bytes();
     /// assert_eq!(bytes, [0x4a, 0x40]);
+    /// # }
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
@@ -715,9 +724,12 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
+    /// # // FIXME(f16_f128): LLVM crashes on s390x, llvm/llvm-project#50374
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let bytes = 12.5f16.to_le_bytes();
     /// assert_eq!(bytes, [0x40, 0x4a]);
+    /// # }
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
@@ -742,6 +754,8 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
+    /// # // FIXME(f16_f128): LLVM crashes on s390x, llvm/llvm-project#50374
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let bytes = 12.5f16.to_ne_bytes();
     /// assert_eq!(
@@ -752,6 +766,7 @@ impl f16 {
     ///         [0x40, 0x4a]
     ///     }
     /// );
+    /// # }
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]

From df72e478b0179581c985ec53ebd6a0d14a330366 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Wed, 10 Jul 2024 18:55:45 -0400
Subject: [PATCH 4/9] Make sure that labels are defined after the primary span
 in diagnostics

---
 .../rustc_macros/src/diagnostics/diagnostic_builder.rs   | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index 46bd80c2df64d..f93d89d6c0f04 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -269,6 +269,7 @@ impl DiagnosticDeriveVariantBuilder {
         let field_binding = &binding_info.binding;
 
         let inner_ty = FieldInnerTy::from_type(&field.ty);
+        let mut seen_label = false;
 
         field
             .attrs
@@ -280,6 +281,14 @@ impl DiagnosticDeriveVariantBuilder {
                 }
 
                 let name = attr.path().segments.last().unwrap().ident.to_string();
+
+                if name == "primary_span" && seen_label {
+                    span_err(attr.span().unwrap(), format!("`#[primary_span]` must be placed before labels, since it overwrites the span of the diagnostic")).emit();
+                }
+                if name == "label" {
+                    seen_label = true;
+                }
+
                 let needs_clone =
                     name == "primary_span" && matches!(inner_ty, FieldInnerTy::Vec(_));
                 let (binding, needs_destructure) = if needs_clone {

From 12ae282987762a71cf146efa3fb6c6fcf4956475 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Wed, 10 Jul 2024 18:55:51 -0400
Subject: [PATCH 5/9] Fix diagnostic and add a test for it

---
 compiler/rustc_resolve/src/errors.rs         | 2 +-
 tests/ui/tool-attributes/invalid-tool.rs     | 6 ++++++
 tests/ui/tool-attributes/invalid-tool.stderr | 8 ++++++++
 3 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 tests/ui/tool-attributes/invalid-tool.rs
 create mode 100644 tests/ui/tool-attributes/invalid-tool.stderr

diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 0620f3d709eb2..cd6503ae444a3 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -1089,8 +1089,8 @@ pub(crate) struct ToolWasAlreadyRegistered {
 #[derive(Diagnostic)]
 #[diag(resolve_tool_only_accepts_identifiers)]
 pub(crate) struct ToolOnlyAcceptsIdentifiers {
-    #[label]
     #[primary_span]
+    #[label]
     pub(crate) span: Span,
     pub(crate) tool: Symbol,
 }
diff --git a/tests/ui/tool-attributes/invalid-tool.rs b/tests/ui/tool-attributes/invalid-tool.rs
new file mode 100644
index 0000000000000..125333231d217
--- /dev/null
+++ b/tests/ui/tool-attributes/invalid-tool.rs
@@ -0,0 +1,6 @@
+#![feature(register_tool)]
+
+#![register_tool(1)]
+//~^ ERROR `register_tool` only accepts identifiers
+
+fn main() {}
diff --git a/tests/ui/tool-attributes/invalid-tool.stderr b/tests/ui/tool-attributes/invalid-tool.stderr
new file mode 100644
index 0000000000000..deafa6d167c20
--- /dev/null
+++ b/tests/ui/tool-attributes/invalid-tool.stderr
@@ -0,0 +1,8 @@
+error: `register_tool` only accepts identifiers
+  --> $DIR/invalid-tool.rs:3:18
+   |
+LL | #![register_tool(1)]
+   |                  ^ not an identifier
+
+error: aborting due to 1 previous error
+

From 27d5db166e8e640ab8317cc96b91ffe60270b6c5 Mon Sep 17 00:00:00 2001
From: Georg Semmler <github@weiznich.de>
Date: Thu, 11 Jul 2024 08:14:28 +0200
Subject: [PATCH 6/9] Allows `#[diagnostic::do_not_recommend]` to supress trait
 impls in suggestions as well

This commit changes the error reporting mechanism for not implemented
traits to skip impl marked as `#[diagnostic::do_not_recommend]` in the
help part of the error message ("the following other types implement
trait `Foo`:"). The main use case here is to allow crate authors to skip
non-meaningful confusing suggestions. A common example for this are
fully generic impls on tuples.
---
 .../traits/fulfillment_errors.rs              | 19 ++++++++++++++
 ...supress_suggestions_in_help.current.stderr | 18 +++++++++++++
 .../supress_suggestions_in_help.next.stderr   | 18 +++++++++++++
 .../supress_suggestions_in_help.rs            | 25 +++++++++++++++++++
 4 files changed, 80 insertions(+)
 create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr
 create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr
 create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs

diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index f7ec5f1ff325f..2e6247b46401d 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1776,6 +1776,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             true
         };
 
+        // we filter before checking if `impl_candidates` is empty
+        // to get the fallback solution if we filtered out any impls
+        let impl_candidates = impl_candidates
+            .into_iter()
+            .cloned()
+            .filter(|cand| {
+                !self.tcx.has_attrs_with_path(
+                    cand.impl_def_id,
+                    &[sym::diagnostic, sym::do_not_recommend],
+                )
+            })
+            .collect::<Vec<_>>();
+
         let def_id = trait_ref.def_id();
         if impl_candidates.is_empty() {
             if self.tcx.trait_is_auto(def_id)
@@ -1788,6 +1801,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             let mut impl_candidates: Vec<_> = self
                 .tcx
                 .all_impls(def_id)
+                // ignore `do_not_recommend` items
+                .filter(|def_id| {
+                    !self
+                        .tcx
+                        .has_attrs_with_path(*def_id, &[sym::diagnostic, sym::do_not_recommend])
+                })
                 // Ignore automatically derived impls and `!Trait` impls.
                 .filter_map(|def_id| self.tcx.impl_trait_header(def_id))
                 .filter_map(|header| {
diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr
new file mode 100644
index 0000000000000..629fc59361dd2
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/supress_suggestions_in_help.rs:23:11
+   |
+LL |     check(());
+   |     ----- ^^ the trait `Foo` is not implemented for `()`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Foo` is implemented for `i32`
+note: required by a bound in `check`
+  --> $DIR/supress_suggestions_in_help.rs:20:18
+   |
+LL | fn check(a: impl Foo) {}
+   |                  ^^^ required by this bound in `check`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr
new file mode 100644
index 0000000000000..629fc59361dd2
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/supress_suggestions_in_help.rs:23:11
+   |
+LL |     check(());
+   |     ----- ^^ the trait `Foo` is not implemented for `()`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Foo` is implemented for `i32`
+note: required by a bound in `check`
+  --> $DIR/supress_suggestions_in_help.rs:20:18
+   |
+LL | fn check(a: impl Foo) {}
+   |                  ^^^ required by this bound in `check`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs
new file mode 100644
index 0000000000000..ef6f255c3518b
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs
@@ -0,0 +1,25 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+#![feature(do_not_recommend)]
+
+trait Foo {}
+
+#[diagnostic::do_not_recommend]
+impl<A> Foo for (A,) {}
+
+#[diagnostic::do_not_recommend]
+impl<A, B> Foo for (A, B) {}
+
+#[diagnostic::do_not_recommend]
+impl<A, B, C> Foo for (A, B, C) {}
+
+impl Foo for i32 {}
+
+fn check(a: impl Foo) {}
+
+fn main() {
+    check(());
+    //~^ ERROR the trait bound `(): Foo` is not satisfied
+}

From ab56fe20533d843b0ad29e969c67e3e0f9c588bf Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross@umich.edu>
Date: Thu, 11 Jul 2024 03:16:45 -0400
Subject: [PATCH 7/9] Rename `lazy_cell_consume` to `lazy_cell_into_inner`

Name this something that is less confusable with an atomic consume API for
`{Lazy,Once}Lock`.
---
 library/core/src/cell/lazy.rs     | 4 ++--
 library/std/src/sync/lazy_lock.rs | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs
index 7c7130ec075e9..21452d40f9ded 100644
--- a/library/core/src/cell/lazy.rs
+++ b/library/core/src/cell/lazy.rs
@@ -67,7 +67,7 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(lazy_cell_consume)]
+    /// #![feature(lazy_cell_into_inner)]
     ///
     /// use std::cell::LazyCell;
     ///
@@ -78,7 +78,7 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
     /// assert_eq!(&*lazy, "HELLO, WORLD!");
     /// assert_eq!(LazyCell::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string()));
     /// ```
-    #[unstable(feature = "lazy_cell_consume", issue = "125623")]
+    #[unstable(feature = "lazy_cell_into_inner", issue = "125623")]
     pub fn into_inner(this: Self) -> Result<T, F> {
         match this.state.into_inner() {
             State::Init(data) => Ok(data),
diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs
index b70c041fa4283..18906aceffa30 100644
--- a/library/std/src/sync/lazy_lock.rs
+++ b/library/std/src/sync/lazy_lock.rs
@@ -107,7 +107,7 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(lazy_cell_consume)]
+    /// #![feature(lazy_cell_into_inner)]
     ///
     /// use std::sync::LazyLock;
     ///
@@ -118,7 +118,7 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
     /// assert_eq!(&*lazy, "HELLO, WORLD!");
     /// assert_eq!(LazyLock::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string()));
     /// ```
-    #[unstable(feature = "lazy_cell_consume", issue = "125623")]
+    #[unstable(feature = "lazy_cell_into_inner", issue = "125623")]
     pub fn into_inner(mut this: Self) -> Result<T, F> {
         let state = this.once.state();
         match state {

From a01f49e7f32b39b77f6a5804c1ed12aadaa89ec5 Mon Sep 17 00:00:00 2001
From: trevyn <230691+trevyn@users.noreply.github.com>
Date: Thu, 11 Jul 2024 12:12:00 +0400
Subject: [PATCH 8/9] check is_ident before parse_ident

---
 compiler/rustc_parse/src/parser/item.rs | 4 ++--
 tests/ui/parser/ice-issue-127600.rs     | 2 ++
 tests/ui/parser/ice-issue-127600.stderr | 8 ++++++++
 3 files changed, 12 insertions(+), 2 deletions(-)
 create mode 100644 tests/ui/parser/ice-issue-127600.rs
 create mode 100644 tests/ui/parser/ice-issue-127600.stderr

diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index f31e634f55c8b..2c98feeece775 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -387,8 +387,8 @@ impl<'a> Parser<'a> {
         let span = if is_pub { self.prev_token.span.to(ident_span) } else { ident_span };
         let insert_span = ident_span.shrink_to_lo();
 
-        let ident = if (!is_const
-            || self.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Parenthesis)))
+        let ident = if self.token.is_ident()
+            && (!is_const || self.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Parenthesis)))
             && self.look_ahead(1, |t| {
                 [
                     token::Lt,
diff --git a/tests/ui/parser/ice-issue-127600.rs b/tests/ui/parser/ice-issue-127600.rs
new file mode 100644
index 0000000000000..709c10253266d
--- /dev/null
+++ b/tests/ui/parser/ice-issue-127600.rs
@@ -0,0 +1,2 @@
+const!(&raw mut a);
+//~^ ERROR expected identifier, found `!`
diff --git a/tests/ui/parser/ice-issue-127600.stderr b/tests/ui/parser/ice-issue-127600.stderr
new file mode 100644
index 0000000000000..629fc4ae40b67
--- /dev/null
+++ b/tests/ui/parser/ice-issue-127600.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `!`
+  --> $DIR/ice-issue-127600.rs:1:6
+   |
+LL | const!(&raw mut a);
+   |      ^ expected identifier
+
+error: aborting due to 1 previous error
+

From 8a50bcbdceacca60126c085c7cad46aced589c87 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov@redhat.com>
Date: Wed, 10 Jul 2024 17:20:21 +0200
Subject: [PATCH 9/9] Remove extern "wasm" ABI

Remove the unstable `extern "wasm"` ABI (`wasm_abi` feature tracked
in #83788).

As discussed in https://github.com/rust-lang/rust/pull/127513#issuecomment-2220410679
and following, this ABI is a failed experiment that did not end
up being used for anything. Keeping support for this ABI in LLVM 19
would require us to switch wasm targets to the `experimental-mv`
ABI, which we do not want to do.

It should be noted that `Abi::Wasm` was internally used for two
things: The `-Z wasm-c-abi=legacy` ABI that is still used by
default on some wasm targets, and the `extern "wasm"` ABI. Despite
both being `Abi::Wasm` internally, they were not the same. An
explicit `extern "wasm"` additionally enabled the `+multivalue`
feature.

I've opted to remove `Abi::Wasm` in this patch entirely, instead
of keeping it as an ABI with only internal usage. Both
`-Z wasm-c-abi` variants are now treated as part of the normal
C ABI, just with different different treatment in
adjust_for_foreign_abi.
---
 compiler/rustc_codegen_llvm/src/attributes.rs | 14 +--
 compiler/rustc_feature/src/removed.rs         |  3 +
 compiler/rustc_feature/src/unstable.rs        |  2 -
 compiler/rustc_middle/src/ty/layout.rs        |  1 -
 .../rustc_smir/src/rustc_internal/internal.rs |  1 -
 .../rustc_smir/src/rustc_smir/convert/ty.rs   |  1 -
 compiler/rustc_target/src/abi/call/mod.rs     | 14 +--
 compiler/rustc_target/src/spec/abi/mod.rs     | 26 +++---
 compiler/rustc_target/src/spec/mod.rs         | 17 +---
 compiler/rustc_ty_utils/src/abi.rs            |  3 +-
 compiler/stable_mir/src/ty.rs                 |  1 -
 tests/run-make/wasm-abi/foo.rs                | 87 -------------------
 tests/run-make/wasm-abi/host.wat              | 22 -----
 tests/run-make/wasm-abi/rmake.rs              | 29 -------
 tests/ui/abi/removed-wasm-abi.rs              |  4 +
 tests/ui/abi/removed-wasm-abi.stderr          | 12 +++
 tests/ui/abi/unsupported.aarch64.stderr       | 24 ++---
 tests/ui/abi/unsupported.arm.stderr           | 22 ++---
 tests/ui/abi/unsupported.i686.stderr          | 18 ++--
 tests/ui/abi/unsupported.riscv32.stderr       | 22 ++---
 tests/ui/abi/unsupported.riscv64.stderr       | 22 ++---
 tests/ui/abi/unsupported.rs                   |  3 -
 tests/ui/abi/unsupported.x64.stderr           | 22 ++---
 .../ui/feature-gates/feature-gate-wasm_abi.rs | 26 ------
 .../feature-gate-wasm_abi.stderr              | 73 ----------------
 25 files changed, 87 insertions(+), 382 deletions(-)
 delete mode 100644 tests/run-make/wasm-abi/foo.rs
 delete mode 100644 tests/run-make/wasm-abi/host.wat
 delete mode 100644 tests/run-make/wasm-abi/rmake.rs
 create mode 100644 tests/ui/abi/removed-wasm-abi.rs
 create mode 100644 tests/ui/abi/removed-wasm-abi.stderr
 delete mode 100644 tests/ui/feature-gates/feature-gate-wasm_abi.rs
 delete mode 100644 tests/ui/feature-gates/feature-gate-wasm_abi.stderr

diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index cd82894af18eb..e766947002639 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -6,7 +6,6 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFuncti
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::config::{FunctionReturn, OptLevel};
 use rustc_span::symbol::sym;
-use rustc_target::spec::abi::Abi;
 use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector};
 use smallvec::SmallVec;
 
@@ -482,7 +481,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
         return;
     }
 
-    let mut function_features = function_features
+    let function_features = function_features
         .iter()
         .flat_map(|feat| {
             llvm_util::to_llvm_features(cx.tcx.sess, feat).into_iter().map(|f| format!("+{f}"))
@@ -504,17 +503,6 @@ pub fn from_fn_attrs<'ll, 'tcx>(
             let name = name.as_str();
             to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-name", name));
         }
-
-        // The `"wasm"` abi on wasm targets automatically enables the
-        // `+multivalue` feature because the purpose of the wasm abi is to match
-        // the WebAssembly specification, which has this feature. This won't be
-        // needed when LLVM enables this `multivalue` feature by default.
-        if !cx.tcx.is_closure_like(instance.def_id()) {
-            let abi = cx.tcx.fn_sig(instance.def_id()).skip_binder().abi();
-            if abi == Abi::Wasm {
-                function_features.push("+multivalue".to_string());
-            }
-        }
     }
 
     let global_features = cx.tcx.global_backend_features(()).iter().map(|s| s.as_str());
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index aea447b2aff10..f13aa506c1ec0 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -215,6 +215,9 @@ declare_features! (
     /// Permits specifying whether a function should permit unwinding or abort on unwind.
     (removed, unwind_attributes, "1.56.0", Some(58760), Some("use the C-unwind ABI instead")),
     (removed, visible_private_types, "1.0.0", None, None),
+    /// Allows `extern "wasm" fn`
+    (removed, wasm_abi, "CURRENT_RUSTC_VERSION", Some(83788),
+     Some("non-standard wasm ABI is no longer supported")),
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
     // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index c05cac155b74b..d7d994d95c51e 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -640,8 +640,6 @@ declare_features! (
     (unstable, unsized_tuple_coercion, "1.20.0", Some(42877)),
     /// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
     (unstable, used_with_arg, "1.60.0", Some(93798)),
-    /// Allows `extern "wasm" fn`
-    (unstable, wasm_abi, "1.53.0", Some(83788)),
     /// Allows `do yeet` expressions
     (unstable, yeet_expr, "1.62.0", Some(96373)),
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index eb25aecd9cef1..22a6786665ca1 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1212,7 +1212,6 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) ->
         | RiscvInterruptM
         | RiscvInterruptS
         | CCmseNonSecureCall
-        | Wasm
         | Unadjusted => false,
         Rust | RustCall | RustCold | RustIntrinsic => {
             tcx.sess.panic_strategy() == PanicStrategy::Unwind
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index 7b5abcf45130d..7c3553b60fddb 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -466,7 +466,6 @@ impl RustcInternal for Abi {
             Abi::AvrInterrupt => rustc_target::spec::abi::Abi::AvrInterrupt,
             Abi::AvrNonBlockingInterrupt => rustc_target::spec::abi::Abi::AvrNonBlockingInterrupt,
             Abi::CCmseNonSecureCall => rustc_target::spec::abi::Abi::CCmseNonSecureCall,
-            Abi::Wasm => rustc_target::spec::abi::Abi::Wasm,
             Abi::System { unwind } => rustc_target::spec::abi::Abi::System { unwind },
             Abi::RustIntrinsic => rustc_target::spec::abi::Abi::RustIntrinsic,
             Abi::RustCall => rustc_target::spec::abi::Abi::RustCall,
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index 9382460d6d403..ef2eb7d52eaef 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -909,7 +909,6 @@ impl<'tcx> Stable<'tcx> for rustc_target::spec::abi::Abi {
             abi::Abi::AvrInterrupt => Abi::AvrInterrupt,
             abi::Abi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt,
             abi::Abi::CCmseNonSecureCall => Abi::CCmseNonSecureCall,
-            abi::Abi::Wasm => Abi::Wasm,
             abi::Abi::System { unwind } => Abi::System { unwind },
             abi::Abi::RustIntrinsic => Abi::RustIntrinsic,
             abi::Abi::RustCall => Abi::RustCall,
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 8058130f44151..9f13c195e4ce6 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -1,6 +1,6 @@
 use crate::abi::{self, Abi, Align, FieldsShape, Size};
 use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout};
-use crate::spec::{self, HasTargetSpec, HasWasmCAbiOpt};
+use crate::spec::{self, HasTargetSpec, HasWasmCAbiOpt, WasmCAbi};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -854,7 +854,8 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             return Ok(());
         }
 
-        match &cx.target_spec().arch[..] {
+        let spec = cx.target_spec();
+        match &spec.arch[..] {
             "x86" => {
                 let flavor = if let spec::abi::Abi::Fastcall { .. }
                 | spec::abi::Abi::Vectorcall { .. } = abi
@@ -901,9 +902,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "sparc" => sparc::compute_abi_info(cx, self),
             "sparc64" => sparc64::compute_abi_info(cx, self),
             "nvptx64" => {
-                if cx.target_spec().adjust_abi(cx, abi, self.c_variadic)
-                    == spec::abi::Abi::PtxKernel
-                {
+                if cx.target_spec().adjust_abi(abi, self.c_variadic) == spec::abi::Abi::PtxKernel {
                     nvptx64::compute_ptx_kernel_abi_info(cx, self)
                 } else {
                     nvptx64::compute_abi_info(self)
@@ -912,13 +911,14 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "hexagon" => hexagon::compute_abi_info(self),
             "xtensa" => xtensa::compute_abi_info(cx, self),
             "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
-            "wasm32" | "wasm64" => {
-                if cx.target_spec().adjust_abi(cx, abi, self.c_variadic) == spec::abi::Abi::Wasm {
+            "wasm32" => {
+                if spec.os == "unknown" && cx.wasm_c_abi_opt() == WasmCAbi::Legacy {
                     wasm::compute_wasm_abi_info(self)
                 } else {
                     wasm::compute_c_abi_info(cx, self)
                 }
             }
+            "wasm64" => wasm::compute_c_abi_info(cx, self),
             "bpf" => bpf::compute_abi_info(self),
             arch => {
                 return Err(AdjustForForeignAbiError::Unsupported {
diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_target/src/spec/abi/mod.rs
index bf51bb4bf8256..0d61345a70e41 100644
--- a/compiler/rustc_target/src/spec/abi/mod.rs
+++ b/compiler/rustc_target/src/spec/abi/mod.rs
@@ -48,7 +48,6 @@ pub enum Abi {
     AvrInterrupt,
     AvrNonBlockingInterrupt,
     CCmseNonSecureCall,
-    Wasm,
     System {
         unwind: bool,
     },
@@ -123,7 +122,6 @@ const AbiDatas: &[AbiData] = &[
     AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt" },
     AbiData { abi: Abi::AvrNonBlockingInterrupt, name: "avr-non-blocking-interrupt" },
     AbiData { abi: Abi::CCmseNonSecureCall, name: "C-cmse-nonsecure-call" },
-    AbiData { abi: Abi::Wasm, name: "wasm" },
     AbiData { abi: Abi::System { unwind: false }, name: "system" },
     AbiData { abi: Abi::System { unwind: true }, name: "system-unwind" },
     AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic" },
@@ -149,6 +147,9 @@ pub fn lookup(name: &str) -> Result<Abi, AbiUnsupported> {
         "riscv-interrupt-u" => AbiUnsupported::Reason {
             explain: "user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314",
         },
+        "wasm" => AbiUnsupported::Reason {
+            explain: "non-standard wasm ABI is no longer supported",
+        },
 
         _ => AbiUnsupported::Unrecognized,
 
@@ -241,10 +242,6 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> {
             feature: sym::abi_c_cmse_nonsecure_call,
             explain: "C-cmse-nonsecure-call ABI is experimental and subject to change",
         }),
-        "wasm" => Err(AbiDisabled::Unstable {
-            feature: sym::wasm_abi,
-            explain: "wasm ABI is experimental and subject to change",
-        }),
         _ => Err(AbiDisabled::Unrecognized),
     }
 }
@@ -287,16 +284,15 @@ impl Abi {
             AvrInterrupt => 23,
             AvrNonBlockingInterrupt => 24,
             CCmseNonSecureCall => 25,
-            Wasm => 26,
             // Cross-platform ABIs
-            System { unwind: false } => 27,
-            System { unwind: true } => 28,
-            RustIntrinsic => 29,
-            RustCall => 30,
-            Unadjusted => 31,
-            RustCold => 32,
-            RiscvInterruptM => 33,
-            RiscvInterruptS => 34,
+            System { unwind: false } => 26,
+            System { unwind: true } => 27,
+            RustIntrinsic => 28,
+            RustCall => 29,
+            Unadjusted => 30,
+            RustCold => 31,
+            RiscvInterruptM => 32,
+            RiscvInterruptS => 33,
         };
         debug_assert!(
             AbiDatas
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 81ada30a59437..607eeac7ccdc3 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2608,22 +2608,8 @@ impl DerefMut for Target {
 
 impl Target {
     /// Given a function ABI, turn it into the correct ABI for this target.
-    pub fn adjust_abi<C>(&self, cx: &C, abi: Abi, c_variadic: bool) -> Abi
-    where
-        C: HasWasmCAbiOpt,
-    {
+    pub fn adjust_abi(&self, abi: Abi, c_variadic: bool) -> Abi {
         match abi {
-            Abi::C { .. } => {
-                if self.arch == "wasm32"
-                    && self.os == "unknown"
-                    && cx.wasm_c_abi_opt() == WasmCAbi::Legacy
-                {
-                    Abi::Wasm
-                } else {
-                    abi
-                }
-            }
-
             // On Windows, `extern "system"` behaves like msvc's `__stdcall`.
             // `__stdcall` only applies on x86 and on non-variadic functions:
             // https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170
@@ -2676,7 +2662,6 @@ impl Target {
             Msp430Interrupt => self.arch == "msp430",
             RiscvInterruptM | RiscvInterruptS => ["riscv32", "riscv64"].contains(&&self.arch[..]),
             AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr",
-            Wasm => ["wasm32", "wasm64"].contains(&&self.arch[..]),
             Thiscall { .. } => self.arch == "x86",
             // On windows these fall-back to platform native calling convention (C) when the
             // architecture is not supported.
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index f078cfe1b2505..4eb7b58bff9fb 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -324,7 +324,7 @@ fn fn_sig_for_fn_abi<'tcx>(
 #[inline]
 fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi, c_variadic: bool) -> Conv {
     use rustc_target::spec::abi::Abi::*;
-    match tcx.sess.target.adjust_abi(&tcx, abi, c_variadic) {
+    match tcx.sess.target.adjust_abi(abi, c_variadic) {
         RustIntrinsic | Rust | RustCall => Conv::Rust,
 
         // This is intentionally not using `Conv::Cold`, as that has to preserve
@@ -352,7 +352,6 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi, c_variadic: bool) -> Conv {
         AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
         RiscvInterruptM => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine },
         RiscvInterruptS => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor },
-        Wasm => Conv::C,
 
         // These API constants ought to be more specific...
         Cdecl { .. } => Conv::C,
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 01e4f1d1f33bc..9b912d1607426 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -1045,7 +1045,6 @@ pub enum Abi {
     AvrInterrupt,
     AvrNonBlockingInterrupt,
     CCmseNonSecureCall,
-    Wasm,
     System { unwind: bool },
     RustIntrinsic,
     RustCall,
diff --git a/tests/run-make/wasm-abi/foo.rs b/tests/run-make/wasm-abi/foo.rs
deleted file mode 100644
index 0678eb3ff51ae..0000000000000
--- a/tests/run-make/wasm-abi/foo.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-#![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/tests/run-make/wasm-abi/host.wat b/tests/run-make/wasm-abi/host.wat
deleted file mode 100644
index e87097ac8a14b..0000000000000
--- a/tests/run-make/wasm-abi/host.wat
+++ /dev/null
@@ -1,22 +0,0 @@
-(module
-  (func (export "two_i32") (result i32 i32)
-      i32.const 100
-      i32.const 101)
-  (func (export "two_i64") (result i64 i64)
-      i64.const 102
-      i64.const 103)
-  (func (export "two_f32") (result f32 f32)
-      f32.const 104
-      f32.const 105)
-  (func (export "two_f64") (result f64 f64)
-      f64.const 106
-      f64.const 107)
-
-  (func (export "mishmash") (result f64 f32 i32 i64 i32 i32)
-      f64.const 108
-      f32.const 109
-      i32.const 110
-      i64.const 111
-      i32.const 112
-      i32.const 113)
-)
diff --git a/tests/run-make/wasm-abi/rmake.rs b/tests/run-make/wasm-abi/rmake.rs
deleted file mode 100644
index ff12bcd536e7f..0000000000000
--- a/tests/run-make/wasm-abi/rmake.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-//@ only-wasm32-wasip1
-//@ needs-wasmtime
-
-use run_make_support::{cmd, rustc};
-use std::path::Path;
-
-fn main() {
-    rustc().input("foo.rs").target("wasm32-wasip1").run();
-
-    let file = Path::new("foo.wasm");
-
-    run(&file, "return_two_i32", "1\n2\n");
-    run(&file, "return_two_i64", "3\n4\n");
-    run(&file, "return_two_f32", "5\n6\n");
-    run(&file, "return_two_f64", "7\n8\n");
-    run(&file, "return_mishmash", "9\n10\n11\n12\n13\n14\n");
-    run(&file, "call_imports", "");
-}
-
-fn run(file: &Path, method: &str, expected_output: &str) {
-    cmd("wasmtime")
-        .arg("run")
-        .arg("--preload=host=host.wat")
-        .arg("--invoke")
-        .arg(method)
-        .arg(file)
-        .run()
-        .assert_stdout_equals(expected_output);
-}
diff --git a/tests/ui/abi/removed-wasm-abi.rs b/tests/ui/abi/removed-wasm-abi.rs
new file mode 100644
index 0000000000000..a45e42bfe020e
--- /dev/null
+++ b/tests/ui/abi/removed-wasm-abi.rs
@@ -0,0 +1,4 @@
+extern "wasm" fn test() {}
+//~^ ERROR invalid ABI: found `wasm`
+
+fn main() {}
diff --git a/tests/ui/abi/removed-wasm-abi.stderr b/tests/ui/abi/removed-wasm-abi.stderr
new file mode 100644
index 0000000000000..6007c4e258014
--- /dev/null
+++ b/tests/ui/abi/removed-wasm-abi.stderr
@@ -0,0 +1,12 @@
+error[E0703]: invalid ABI: found `wasm`
+  --> $DIR/removed-wasm-abi.rs:1:8
+   |
+LL | extern "wasm" fn test() {}
+   |        ^^^^^^ invalid ABI
+   |
+   = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+   = note: non-standard wasm ABI is no longer supported
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0703`.
diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr
index 72a9519e3e772..123e76632574a 100644
--- a/tests/ui/abi/unsupported.aarch64.stderr
+++ b/tests/ui/abi/unsupported.aarch64.stderr
@@ -1,53 +1,47 @@
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:29:1
+  --> $DIR/unsupported.rs:28:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0570]: `"wasm"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:31:1
-   |
-LL | extern "wasm" fn wasm() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:30:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:39:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:41:1
+  --> $DIR/unsupported.rs:38:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:43:1
+  --> $DIR/unsupported.rs:40:1
    |
 LL | extern "riscv-interrupt-m" fn riscv() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:48:1
+  --> $DIR/unsupported.rs:45:1
    |
 LL | extern "x86-interrupt" fn x86() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:53:1
+  --> $DIR/unsupported.rs:50:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:59:1
+  --> $DIR/unsupported.rs:56:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,6 +50,6 @@ LL | extern "stdcall" fn stdcall() {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-error: aborting due to 8 previous errors; 1 warning emitted
+error: aborting due to 7 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr
index 473b59a334df3..7376bb17d6b95 100644
--- a/tests/ui/abi/unsupported.arm.stderr
+++ b/tests/ui/abi/unsupported.arm.stderr
@@ -1,47 +1,41 @@
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:29:1
+  --> $DIR/unsupported.rs:28:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0570]: `"wasm"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:31:1
-   |
-LL | extern "wasm" fn wasm() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:39:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:41:1
+  --> $DIR/unsupported.rs:38:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:43:1
+  --> $DIR/unsupported.rs:40:1
    |
 LL | extern "riscv-interrupt-m" fn riscv() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:48:1
+  --> $DIR/unsupported.rs:45:1
    |
 LL | extern "x86-interrupt" fn x86() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:53:1
+  --> $DIR/unsupported.rs:50:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:59:1
+  --> $DIR/unsupported.rs:56:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,6 +44,6 @@ LL | extern "stdcall" fn stdcall() {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-error: aborting due to 7 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr
index f0af3d251e245..23b0e581887f4 100644
--- a/tests/ui/abi/unsupported.i686.stderr
+++ b/tests/ui/abi/unsupported.i686.stderr
@@ -1,39 +1,33 @@
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:29:1
+  --> $DIR/unsupported.rs:28:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0570]: `"wasm"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:31:1
-   |
-LL | extern "wasm" fn wasm() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:30:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:39:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:41:1
+  --> $DIR/unsupported.rs:38:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:43:1
+  --> $DIR/unsupported.rs:40:1
    |
 LL | extern "riscv-interrupt-m" fn riscv() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr
index b466a2a6ff86b..708fd2c92a998 100644
--- a/tests/ui/abi/unsupported.riscv32.stderr
+++ b/tests/ui/abi/unsupported.riscv32.stderr
@@ -1,47 +1,41 @@
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:29:1
+  --> $DIR/unsupported.rs:28:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0570]: `"wasm"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:31:1
-   |
-LL | extern "wasm" fn wasm() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:30:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:39:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:41:1
+  --> $DIR/unsupported.rs:38:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:48:1
+  --> $DIR/unsupported.rs:45:1
    |
 LL | extern "x86-interrupt" fn x86() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:53:1
+  --> $DIR/unsupported.rs:50:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:59:1
+  --> $DIR/unsupported.rs:56:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,6 +44,6 @@ LL | extern "stdcall" fn stdcall() {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-error: aborting due to 7 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr
index b466a2a6ff86b..708fd2c92a998 100644
--- a/tests/ui/abi/unsupported.riscv64.stderr
+++ b/tests/ui/abi/unsupported.riscv64.stderr
@@ -1,47 +1,41 @@
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:29:1
+  --> $DIR/unsupported.rs:28:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0570]: `"wasm"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:31:1
-   |
-LL | extern "wasm" fn wasm() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:30:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:39:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:41:1
+  --> $DIR/unsupported.rs:38:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:48:1
+  --> $DIR/unsupported.rs:45:1
    |
 LL | extern "x86-interrupt" fn x86() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:53:1
+  --> $DIR/unsupported.rs:50:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:59:1
+  --> $DIR/unsupported.rs:56:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,6 +44,6 @@ LL | extern "stdcall" fn stdcall() {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-error: aborting due to 7 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs
index cd7e76c7158f4..c12883e3fce21 100644
--- a/tests/ui/abi/unsupported.rs
+++ b/tests/ui/abi/unsupported.rs
@@ -19,7 +19,6 @@
     abi_ptx,
     abi_msp430_interrupt,
     abi_avr_interrupt,
-    wasm_abi,
     abi_x86_interrupt,
     abi_riscv_interrupt
 )]
@@ -28,8 +27,6 @@ trait Sized {}
 
 extern "ptx-kernel" fn ptx() {}
 //~^ ERROR is not a supported ABI
-extern "wasm" fn wasm() {}
-//~^ ERROR is not a supported ABI
 extern "aapcs" fn aapcs() {}
 //[x64]~^ ERROR is not a supported ABI
 //[i686]~^^ ERROR is not a supported ABI
diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr
index 4a2b7e7496920..7b918a948d3ba 100644
--- a/tests/ui/abi/unsupported.x64.stderr
+++ b/tests/ui/abi/unsupported.x64.stderr
@@ -1,47 +1,41 @@
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:29:1
+  --> $DIR/unsupported.rs:28:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0570]: `"wasm"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:31:1
-   |
-LL | extern "wasm" fn wasm() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:30:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:39:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:41:1
+  --> $DIR/unsupported.rs:38:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:43:1
+  --> $DIR/unsupported.rs:40:1
    |
 LL | extern "riscv-interrupt-m" fn riscv() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:53:1
+  --> $DIR/unsupported.rs:50:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:59:1
+  --> $DIR/unsupported.rs:56:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,6 +44,6 @@ LL | extern "stdcall" fn stdcall() {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-error: aborting due to 7 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/feature-gates/feature-gate-wasm_abi.rs b/tests/ui/feature-gates/feature-gate-wasm_abi.rs
deleted file mode 100644
index da1d9300a2bde..0000000000000
--- a/tests/ui/feature-gates/feature-gate-wasm_abi.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-//@ needs-llvm-components: webassembly
-//@ compile-flags: --target=wasm32-unknown-unknown --crate-type=rlib
-#![no_core]
-#![feature(no_core, lang_items)]
-#[lang="sized"]
-trait Sized { }
-
-extern "wasm" fn fu() {} //~ ERROR wasm ABI is experimental
-
-trait T {
-    extern "wasm" fn mu(); //~ ERROR wasm ABI is experimental
-    extern "wasm" fn dmu() {} //~ ERROR wasm ABI is experimental
-}
-
-struct S;
-impl T for S {
-    extern "wasm" fn mu() {} //~ ERROR wasm ABI is experimental
-}
-
-impl S {
-    extern "wasm" fn imu() {} //~ ERROR wasm ABI is experimental
-}
-
-type TAU = extern "wasm" fn(); //~ ERROR wasm ABI is experimental
-
-extern "wasm" {} //~ ERROR wasm ABI is experimental
diff --git a/tests/ui/feature-gates/feature-gate-wasm_abi.stderr b/tests/ui/feature-gates/feature-gate-wasm_abi.stderr
deleted file mode 100644
index 973c42af19c58..0000000000000
--- a/tests/ui/feature-gates/feature-gate-wasm_abi.stderr
+++ /dev/null
@@ -1,73 +0,0 @@
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-wasm_abi.rs:8:8
-   |
-LL | extern "wasm" fn fu() {}
-   |        ^^^^^^
-   |
-   = 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
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-wasm_abi.rs:11:12
-   |
-LL |     extern "wasm" fn mu();
-   |            ^^^^^^
-   |
-   = 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
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-wasm_abi.rs:12:12
-   |
-LL |     extern "wasm" fn dmu() {}
-   |            ^^^^^^
-   |
-   = 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
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-wasm_abi.rs:17:12
-   |
-LL |     extern "wasm" fn mu() {}
-   |            ^^^^^^
-   |
-   = 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
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-wasm_abi.rs:21:12
-   |
-LL |     extern "wasm" fn imu() {}
-   |            ^^^^^^
-   |
-   = 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
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-wasm_abi.rs:24:19
-   |
-LL | type TAU = 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
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-wasm_abi.rs:26: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
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 7 previous errors
-
-For more information about this error, try `rustc --explain E0658`.