From 2358e3eff604a770d5dabab9680d81148106fd68 Mon Sep 17 00:00:00 2001
From: Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
Date: Wed, 7 Aug 2019 13:19:07 +0900
Subject: [PATCH] Revert "Rollup merge of #62150 - alex:mem-uninit-refactor,
 r=RalfJung"

This reverts commit 1d45156866b54c3fc36edfdfcdd8149ad9cb5711, reversing
changes made to 0f92eb8a4a7d8715381f5b5d748d22315f6ff9c7.
---
 src/libcore/intrinsics.rs                  | 19 +++++++++++++++++--
 src/libcore/mem/mod.rs                     | 10 ++++++++--
 src/librustc_codegen_llvm/intrinsic.rs     |  2 +-
 src/librustc_typeck/check/intrinsic.rs     |  1 +
 src/test/ui/intrinsics/intrinsic-uninit.rs | 13 +++++++++++++
 5 files changed, 40 insertions(+), 5 deletions(-)
 create mode 100644 src/test/ui/intrinsics/intrinsic-uninit.rs

diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 56e45c3695f61..ceaa870d2b3f7 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -707,11 +707,26 @@ extern "rust-intrinsic" {
                          they should be used through stabilized interfaces \
                          in the rest of the standard library",
                issue = "0")]
-    #[rustc_deprecated(reason = "no longer used by rustc, will be removed - use MaybeUninit \
-                                 instead",
+    #[rustc_deprecated(reason = "superseded by MaybeUninit, removal planned",
                        since = "1.38.0")]
     pub fn init<T>() -> T;
 
+    /// Creates an uninitialized value.
+    ///
+    /// `uninit` is unsafe because there is no guarantee of what its
+    /// contents are. In particular its drop-flag may be set to any
+    /// state, which means it may claim either dropped or
+    /// undropped. In the general case one must use `ptr::write` to
+    /// initialize memory previous set to the result of `uninit`.
+    #[unstable(feature = "core_intrinsics",
+               reason = "intrinsics are unlikely to ever be stabilized, instead \
+                         they should be used through stabilized interfaces \
+                         in the rest of the standard library",
+               issue = "0")]
+    #[rustc_deprecated(reason = "superseded by MaybeUninit, removal planned",
+                       since = "1.38.0")]
+    pub fn uninit<T>() -> T;
+
     /// Moves a value out of scope without running drop glue.
     pub fn forget<T: ?Sized>(_: T);
 
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index 86dae985fdb00..2b462f08d42dc 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -452,8 +452,11 @@ pub const fn needs_drop<T>() -> bool {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(bootstrap, allow(deprecated_in_future))]
+#[allow(deprecated)]
 pub unsafe fn zeroed<T>() -> T {
-    MaybeUninit::zeroed().assume_init()
+    intrinsics::panic_if_uninhabited::<T>();
+    intrinsics::init()
 }
 
 /// Bypasses Rust's normal memory-initialization checks by pretending to
@@ -477,8 +480,11 @@ pub unsafe fn zeroed<T>() -> T {
 #[inline]
 #[rustc_deprecated(since = "1.39.0", reason = "use `mem::MaybeUninit` instead")]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(bootstrap, allow(deprecated_in_future))]
+#[allow(deprecated)]
 pub unsafe fn uninitialized<T>() -> T {
-    MaybeUninit::uninit().assume_init()
+    intrinsics::panic_if_uninhabited::<T>();
+    intrinsics::uninit()
 }
 
 /// Swaps the values at two mutable locations, without deinitializing either one.
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 199170182e4b4..a9b8962f45b1b 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -232,7 +232,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                 return;
             }
             // Effectively no-ops
-            "forget" => {
+            "uninit" | "forget" => {
                 return;
             }
             "needs_drop" => {
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 4d8f564123634..8bb24eef5e94c 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -145,6 +145,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
             "rustc_peek" => (1, vec![param(0)], param(0)),
             "panic_if_uninhabited" => (1, Vec::new(), tcx.mk_unit()),
             "init" => (1, Vec::new(), param(0)),
+            "uninit" => (1, Vec::new(), param(0)),
             "forget" => (1, vec![param(0)], tcx.mk_unit()),
             "transmute" => (2, vec![ param(0) ], param(1)),
             "move_val_init" => {
diff --git a/src/test/ui/intrinsics/intrinsic-uninit.rs b/src/test/ui/intrinsics/intrinsic-uninit.rs
new file mode 100644
index 0000000000000..9555efb639b50
--- /dev/null
+++ b/src/test/ui/intrinsics/intrinsic-uninit.rs
@@ -0,0 +1,13 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+#![feature(intrinsics)]
+
+mod rusti {
+    extern "rust-intrinsic" {
+        pub fn uninit<T>() -> T;
+    }
+}
+pub fn main() {
+    let _a : isize = unsafe {rusti::uninit()};
+}