From bdd480a44b45802b4870ce95cdd704ff1b8be50a Mon Sep 17 00:00:00 2001
From: Manish Goregaokar <manishsmail@gmail.com>
Date: Sun, 23 Apr 2023 09:37:00 -0700
Subject: [PATCH] Reintroduce alloc_error_handler as deprecated

---
 .../src/alloc_error_handler.rs                | 13 ++++++++++++
 compiler/rustc_builtin_macros/src/lib.rs      |  2 ++
 compiler/rustc_feature/src/active.rs          |  2 ++
 compiler/rustc_feature/src/removed.rs         |  2 --
 library/core/src/macros/mod.rs                |  9 ++++++++
 library/core/src/prelude/v1.rs                |  3 ++-
 library/std/src/lib.rs                        |  1 +
 library/std/src/prelude/v1.rs                 |  3 ++-
 .../alloc-error-handler-deprecated.rs         | 13 ++++++++++++
 .../alloc-error-handler-deprecated.stderr     | 21 +++++++++++++++++++
 .../feature-gate-alloc-error-handler.rs       | 16 ++++++++++++++
 .../feature-gate-alloc-error-handler.stderr   | 20 ++++++++++++++++++
 12 files changed, 101 insertions(+), 4 deletions(-)
 create mode 100644 compiler/rustc_builtin_macros/src/alloc_error_handler.rs
 create mode 100644 tests/ui/alloc-error/alloc-error-handler-deprecated.rs
 create mode 100644 tests/ui/alloc-error/alloc-error-handler-deprecated.stderr
 create mode 100644 tests/ui/feature-gates/feature-gate-alloc-error-handler.rs
 create mode 100644 tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr

diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
new file mode 100644
index 0000000000000..ca18d0048977f
--- /dev/null
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -0,0 +1,13 @@
+use rustc_expand::base::{Annotatable, ExtCtxt};
+use rustc_span::Span;
+
+pub fn expand(
+    _ecx: &mut ExtCtxt<'_>,
+    _span: Span,
+    _meta_item: &rustc_ast::MetaItem,
+    item: Annotatable,
+) -> Vec<Annotatable> {
+
+    vec![item.clone()]
+}
+
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index b6170161d6b6b..8f86ef44aa3ab 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -27,6 +27,7 @@ use rustc_expand::proc_macro::BangProcMacro;
 use rustc_fluent_macro::fluent_messages;
 use rustc_span::symbol::sym;
 
+mod alloc_error_handler;
 mod assert;
 mod cfg;
 mod cfg_accessible;
@@ -103,6 +104,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
     }
 
     register_attr! {
+        alloc_error_handler: alloc_error_handler::expand,
         bench: test::expand_bench,
         cfg_accessible: cfg_accessible::Expander,
         cfg_eval: cfg_eval::expand,
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 594e6cca912e7..5743f7eb67c56 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -291,6 +291,8 @@ declare_features! (
     (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
     /// Allows additional const parameter types, such as `&'static str` or user defined types
     (incomplete, adt_const_params, "1.56.0", Some(95174), None),
+    /// Deprecated feature; exists for smooth transitions
+    (active, alloc_error_handler, "1.29.0", Some(51540), None),
     /// Allows trait methods with arbitrary self types.
     (active, arbitrary_self_types, "1.23.0", Some(44874), None),
     /// Allows using `const` operands in inline assembly.
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index c978d6472c8d5..876a31abdf882 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -47,8 +47,6 @@ declare_features! (
 
     (removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
      Some("merged into `#![feature(slice_patterns)]`")),
-    /// Allows defining an `#[alloc_error_handler]`.
-    (removed, alloc_error_handler, "CURRENT_RUSTC_VERSION", Some(51540), None, Some("now handled by panic handler")),
     (removed, allocator, "1.0.0", None, None, None),
     /// Allows a test to fail without failing the whole suite.
     (removed, allow_fail, "1.19.0", Some(46488), None, Some("removed due to no clear use cases")),
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index cc3179ee7801b..03daad6722e36 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1531,6 +1531,15 @@ pub(crate) mod builtin {
         /* compiler built-in */
     }
 
+    /// Deprecated attribute for functionality now handled by panic_handler
+    #[unstable(feature = "alloc_error_handler", issue = "51540")]
+    #[deprecated(since = "1.71", note = "Please use #[panic_handler] instead")]
+    #[allow_internal_unstable(rustc_attrs)]
+    #[rustc_builtin_macro]
+    pub macro alloc_error_handler($item:item) {
+        /* compiler built-in */
+    }
+
     /// Keeps the item it's applied to if the passed path is accessible, and removes it otherwise.
     #[unstable(
         feature = "cfg_accessible",
diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs
index 9c4c0f6ab7aa5..f988a55e1438a 100644
--- a/library/core/src/prelude/v1.rs
+++ b/library/core/src/prelude/v1.rs
@@ -76,7 +76,8 @@ pub use crate::macros::builtin::{RustcDecodable, RustcEncodable};
 // Do not `doc(no_inline)` so that they become doc items on their own
 // (no public module for them to be re-exported from).
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
-pub use crate::macros::builtin::{bench, derive, global_allocator, test, test_case};
+#[allow(deprecated)]
+pub use crate::macros::builtin::{alloc_error_handler, bench, derive, global_allocator, test, test_case};
 
 #[unstable(feature = "derive_const", issue = "none")]
 pub use crate::macros::builtin::derive_const;
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 933f75d638ba4..31400aa182058 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -236,6 +236,7 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![feature(alloc_error_handler)]
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
 #![feature(allow_internal_unstable)]
diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs
index 4f325a70b1891..bc694fef6f51c 100644
--- a/library/std/src/prelude/v1.rs
+++ b/library/std/src/prelude/v1.rs
@@ -60,7 +60,8 @@ pub use core::prelude::v1::{RustcDecodable, RustcEncodable};
 // Do not `doc(no_inline)` so that they become doc items on their own
 // (no public module for them to be re-exported from).
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
-pub use core::prelude::v1::{bench, derive, global_allocator, test, test_case};
+#[allow(deprecated)]
+pub use core::prelude::v1::{alloc_error_handler, bench, derive, global_allocator, test, test_case};
 
 #[unstable(feature = "derive_const", issue = "none")]
 pub use core::prelude::v1::derive_const;
diff --git a/tests/ui/alloc-error/alloc-error-handler-deprecated.rs b/tests/ui/alloc-error/alloc-error-handler-deprecated.rs
new file mode 100644
index 0000000000000..e73e058a8e1a3
--- /dev/null
+++ b/tests/ui/alloc-error/alloc-error-handler-deprecated.rs
@@ -0,0 +1,13 @@
+#![feature(alloc_error_handler)]
+#![deny(deprecated)]
+
+
+extern crate alloc;
+use alloc::layout::Layout;
+
+#[alloc_error_handler]
+fn alloc_error(_l: Layout) -> ! {
+    loop {}
+}
+
+fn main() {}
diff --git a/tests/ui/alloc-error/alloc-error-handler-deprecated.stderr b/tests/ui/alloc-error/alloc-error-handler-deprecated.stderr
new file mode 100644
index 0000000000000..6bd7aa9b3d875
--- /dev/null
+++ b/tests/ui/alloc-error/alloc-error-handler-deprecated.stderr
@@ -0,0 +1,21 @@
+error[E0432]: unresolved import `alloc::layout`
+  --> $DIR/alloc-error-handler-deprecated.rs:6:12
+   |
+LL | use alloc::layout::Layout;
+   |            ^^^^^^ could not find `layout` in `alloc`
+
+error: use of deprecated macro `alloc_error_handler`: Please use #[panic_handler] instead
+  --> $DIR/alloc-error-handler-deprecated.rs:8:3
+   |
+LL | #[alloc_error_handler]
+   |   ^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/alloc-error-handler-deprecated.rs:2:9
+   |
+LL | #![deny(deprecated)]
+   |         ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/feature-gates/feature-gate-alloc-error-handler.rs b/tests/ui/feature-gates/feature-gate-alloc-error-handler.rs
new file mode 100644
index 0000000000000..78d189d20b64d
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-alloc-error-handler.rs
@@ -0,0 +1,16 @@
+// compile-flags:-C panic=abort
+
+#![no_std]
+#![no_main]
+
+use core::alloc::Layout;
+
+#[alloc_error_handler] //~ ERROR use of unstable library feature 'alloc_error_handler'
+fn oom(info: Layout) -> ! {
+    loop {}
+}
+
+#[panic_handler]
+fn panic(_: &core::panic::PanicInfo) -> ! {
+    loop {}
+}
diff --git a/tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr b/tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr
new file mode 100644
index 0000000000000..54a3962e0e3e3
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr
@@ -0,0 +1,20 @@
+error[E0658]: use of unstable library feature 'alloc_error_handler'
+  --> $DIR/feature-gate-alloc-error-handler.rs:8:3
+   |
+LL | #[alloc_error_handler]
+   |   ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51540 <https://github.com/rust-lang/rust/issues/51540> for more information
+   = help: add `#![feature(alloc_error_handler)]` to the crate attributes to enable
+
+warning: use of deprecated macro `alloc_error_handler`: Please use #[panic_handler] instead
+  --> $DIR/feature-gate-alloc-error-handler.rs:8:3
+   |
+LL | #[alloc_error_handler]
+   |   ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0658`.