From 181716a16cfd088108463b5f9130af75a5993a93 Mon Sep 17 00:00:00 2001
From: tamaron <tamaron1203@gmail.com>
Date: Thu, 11 Nov 2021 11:40:34 +0900
Subject: [PATCH 1/7] compare between Path instead of str

---
 library/std/src/fs/tests.rs | 15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 628de13156c67..1417d860c47f5 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -833,20 +833,11 @@ fn symlink_noexist() {
 fn read_link() {
     if cfg!(windows) {
         // directory symlink
-        assert_eq!(
-            check!(fs::read_link(r"C:\Users\All Users")).to_str().unwrap(),
-            r"C:\ProgramData"
-        );
+        assert_eq!(check!(fs::read_link(r"C:\Users\All Users")), Path::new(r"C:\ProgramData"));
         // junction
-        assert_eq!(
-            check!(fs::read_link(r"C:\Users\Default User")).to_str().unwrap(),
-            r"C:\Users\Default"
-        );
+        assert_eq!(check!(fs::read_link(r"C:\Users\Default User")), Path::new(r"C:\Users\Default"));
         // junction with special permissions
-        assert_eq!(
-            check!(fs::read_link(r"C:\Documents and Settings\")).to_str().unwrap(),
-            r"C:\Users"
-        );
+        assert_eq!(check!(fs::read_link(r"C:\Documents and Settings\")), Path::new(r"C:\Users"));
     }
     let tmpdir = tmpdir();
     let link = tmpdir.join("link");

From a24e2eddb1f5b1fca76eb1a3a6079188f9d54fd7 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Fri, 12 Nov 2021 09:09:08 -0800
Subject: [PATCH 2/7] Android is not GNU

---
 compiler/rustc_target/src/spec/android_base.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_target/src/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs
index aaf81648c51b3..0f01a78c8c592 100644
--- a/compiler/rustc_target/src/spec/android_base.rs
+++ b/compiler/rustc_target/src/spec/android_base.rs
@@ -1,7 +1,7 @@
 use crate::spec::{LinkerFlavor, TargetOptions};
 
 pub fn opts() -> TargetOptions {
-    let mut base = super::linux_gnu_base::opts();
+    let mut base = super::linux_base::opts();
     base.os = "android".to_string();
     // Many of the symbols defined in compiler-rt are also defined in libgcc.
     // Android's linker doesn't like that by default.

From 94ca0b392df7c0f551c136394bf3456bee041357 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 13 Nov 2021 20:55:33 -0500
Subject: [PATCH 3/7] fix ICE on Miri/CTFE copy of half a pointer

---
 .../rustc_const_eval/src/interpret/memory.rs  | 13 +++++-----
 src/test/ui/consts/issue-miri-1910.rs         | 12 +++++++++
 src/test/ui/consts/issue-miri-1910.stderr     | 26 +++++++++++++++++++
 3 files changed, 44 insertions(+), 7 deletions(-)
 create mode 100644 src/test/ui/consts/issue-miri-1910.rs
 create mode 100644 src/test/ui/consts/issue-miri-1910.stderr

diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index b8b6ff93753f0..4aa3c83cc0243 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -1057,20 +1057,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
             Some(dest_ptr) => dest_ptr,
         };
 
+        // This checks relocation edges on the src, which needs to happen before
+        // `prepare_relocation_copy`.
+        let src_bytes = src_alloc
+            .get_bytes_with_uninit_and_ptr(&tcx, src_range)
+            .map_err(|e| e.to_interp_error(src_alloc_id))?
+            .as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
         // first copy the relocations to a temporary buffer, because
         // `get_bytes_mut` will clear the relocations, which is correct,
         // since we don't want to keep any relocations at the target.
-        // (`get_bytes_with_uninit_and_ptr` below checks that there are no
-        // relocations overlapping the edges; those would not be handled correctly).
         let relocations =
             src_alloc.prepare_relocation_copy(self, src_range, dest_offset, num_copies);
         // Prepare a copy of the initialization mask.
         let compressed = src_alloc.compress_uninit_range(src_range);
-        // This checks relocation edges on the src.
-        let src_bytes = src_alloc
-            .get_bytes_with_uninit_and_ptr(&tcx, src_range)
-            .map_err(|e| e.to_interp_error(src_alloc_id))?
-            .as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
 
         // Destination alloc preparations and access hooks.
         let (dest_alloc, extra) = self.get_raw_mut(dest_alloc_id)?;
diff --git a/src/test/ui/consts/issue-miri-1910.rs b/src/test/ui/consts/issue-miri-1910.rs
new file mode 100644
index 0000000000000..20efa145dbe1e
--- /dev/null
+++ b/src/test/ui/consts/issue-miri-1910.rs
@@ -0,0 +1,12 @@
+// error-pattern unable to turn pointer into raw bytes
+#![feature(const_ptr_read)]
+#![feature(const_ptr_offset)]
+
+const C: () = unsafe {
+    let foo = Some(&42 as *const i32);
+    let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3;
+    (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
+};
+
+fn main() {
+}
diff --git a/src/test/ui/consts/issue-miri-1910.stderr b/src/test/ui/consts/issue-miri-1910.stderr
new file mode 100644
index 0000000000000..e2f4ef635887c
--- /dev/null
+++ b/src/test/ui/consts/issue-miri-1910.stderr
@@ -0,0 +1,26 @@
+error: any use of this value will cause an error
+  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |
+LL |           copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |           |
+   |           unable to turn pointer into raw bytes
+   |           inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |           inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+   |           inside `C` at $DIR/issue-miri-1910.rs:8:5
+   |
+  ::: $DIR/issue-miri-1910.rs:5:1
+   |
+LL | / const C: () = unsafe {
+LL | |     let foo = Some(&42 as *const i32);
+LL | |     let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3;
+LL | |     (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
+LL | | };
+   | |__-
+   |
+   = note: `#[deny(const_err)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: aborting due to previous error
+

From 50ec47aa06e96a195707fb5ee92fcd32299ca272 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403@users.noreply.github.com>
Date: Sun, 14 Nov 2021 14:01:30 +0100
Subject: [PATCH 4/7] Remove workaround for the forward progress handling in
 LLVM

---
 compiler/rustc_codegen_gcc/src/intrinsic/mod.rs    |  6 +-----
 compiler/rustc_codegen_llvm/src/context.rs         |  1 -
 compiler/rustc_codegen_llvm/src/intrinsic.rs       |  9 ---------
 compiler/rustc_codegen_ssa/src/mir/block.rs        | 11 -----------
 compiler/rustc_codegen_ssa/src/traits/intrinsic.rs |  4 ----
 5 files changed, 1 insertion(+), 30 deletions(-)

diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 64bd586662d38..f3a2382ef32d9 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -316,7 +316,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                     extended_asm.add_input_operand(None, "r", result.llval);
                     extended_asm.add_clobber("memory");
                     extended_asm.set_volatile_flag(true);
-                    
+
                     // We have copied the value to `result` already.
                     return;
                 }
@@ -363,10 +363,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
         cond
     }
 
-    fn sideeffect(&mut self) {
-        // TODO(antoyo)
-    }
-
     fn type_test(&mut self, _pointer: Self::Value, _typeid: Self::Value) -> Self::Value {
         // Unsupported.
         self.context.new_rvalue_from_int(self.int_type, 0)
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 1dba264a9614a..613a8df891ce4 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -597,7 +597,6 @@ impl CodegenCx<'b, 'tcx> {
         ifn!("llvm.trap", fn() -> void);
         ifn!("llvm.debugtrap", fn() -> void);
         ifn!("llvm.frameaddress", fn(t_i32) -> i8p);
-        ifn!("llvm.sideeffect", fn() -> void);
 
         ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
         ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 924bb803b368f..a7e34b080594b 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -392,15 +392,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         self.call_intrinsic("llvm.expect.i1", &[cond, self.const_bool(expected)])
     }
 
-    fn sideeffect(&mut self) {
-        // This kind of check would make a ton of sense in the caller, but currently the only
-        // caller of this function is in `rustc_codegen_ssa`, which is agnostic to whether LLVM
-        // codegen backend being used, and so is unable to check the LLVM version.
-        if unsafe { llvm::LLVMRustVersionMajor() } < 12 {
-            self.call_intrinsic("llvm.sideeffect", &[]);
-        }
-    }
-
     fn type_test(&mut self, pointer: Self::Value, typeid: Self::Value) -> Self::Value {
         // Test the called operand using llvm.type.test intrinsic. The LowerTypeTests link-time
         // optimization pass replaces calls to this intrinsic with code to test type membership.
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index a9471f7b77160..c8f388bfa1d5a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -980,17 +980,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
 
             mir::TerminatorKind::Goto { target } => {
-                if bb == target {
-                    // This is an unconditional branch back to this same basic block. That means we
-                    // have something like a `loop {}` statement. LLVM versions before 12.0
-                    // miscompile this because they assume forward progress. For older versions
-                    // try to handle just this specific case which comes up commonly in practice
-                    // (e.g., in embedded code).
-                    //
-                    // NB: the `sideeffect` currently checks for the LLVM version used internally.
-                    bx.sideeffect();
-                }
-
                 helper.funclet_br(self, &mut bx, target);
             }
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
index 78bf22ef9f2e2..02be6cd360c72 100644
--- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
@@ -20,10 +20,6 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
     fn abort(&mut self);
     fn assume(&mut self, val: Self::Value);
     fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value;
-    /// Emits a forced side effect.
-    ///
-    /// Currently has any effect only when LLVM versions prior to 12.0 are used as the backend.
-    fn sideeffect(&mut self);
     /// Trait method used to test whether a given pointer is associated with a type identifier.
     fn type_test(&mut self, pointer: Self::Value, typeid: Self::Value) -> Self::Value;
     /// Trait method used to inject `va_start` on the "spoofed" `VaListImpl` in

From 60595f7bde03c6c17a798f1aed6fb8bedd9bd3ca Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 14 Nov 2021 11:56:52 -0500
Subject: [PATCH 5/7] disable portable SIMD tests in Miri

---
 library/core/src/lib.rs    | 2 ++
 library/core/tests/simd.rs | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 1099877a00850..74ae0fb91c74c 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -402,11 +402,13 @@ pub mod arch {
 #[allow(missing_debug_implementations, dead_code, unsafe_op_in_unsafe_fn, unused_unsafe)]
 #[allow(rustdoc::bare_urls)]
 #[unstable(feature = "portable_simd", issue = "86656")]
+#[cfg(not(all(miri, doctest)))] // Miri does not support all SIMD intrinsics
 #[cfg(not(bootstrap))]
 mod core_simd;
 
 #[doc = include_str!("../../portable-simd/crates/core_simd/src/core_simd_docs.md")]
 #[unstable(feature = "portable_simd", issue = "86656")]
+#[cfg(not(all(miri, doctest)))] // Miri does not support all SIMD intrinsics
 #[cfg(not(bootstrap))]
 pub mod simd {
     #[unstable(feature = "portable_simd", issue = "86656")]
diff --git a/library/core/tests/simd.rs b/library/core/tests/simd.rs
index 8c11d788c67ae..50c92968c9d82 100644
--- a/library/core/tests/simd.rs
+++ b/library/core/tests/simd.rs
@@ -1,3 +1,5 @@
+#![cfg(not(miri))] // Miri does not support all SIMD intrinsics
+
 use core::simd::f32x4;
 
 #[test]

From eebf676bf8f76fcdfa610e7e46ab6c135a9cd2d0 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 14 Nov 2021 13:28:47 -0500
Subject: [PATCH 6/7] fix getting the discriminant of a zero-variant enum

---
 compiler/rustc_middle/src/ty/sty.rs      | 4 +++-
 src/test/ui/consts/const_discriminant.rs | 6 ++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index e57075ed33811..59601e1484956 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -2067,7 +2067,9 @@ impl<'tcx> TyS<'tcx> {
     ) -> Option<Discr<'tcx>> {
         match self.kind() {
             TyKind::Adt(adt, _) if adt.variants.is_empty() => {
-                bug!("discriminant_for_variant called on zero variant enum");
+                // This can actually happen during CTFE, see
+                // https://github.com/rust-lang/rust/issues/89765.
+                None
             }
             TyKind::Adt(adt, _) if adt.is_enum() => {
                 Some(adt.discriminant_for_variant(tcx, variant_index))
diff --git a/src/test/ui/consts/const_discriminant.rs b/src/test/ui/consts/const_discriminant.rs
index a47f6af02965b..a9c0217ae2421 100644
--- a/src/test/ui/consts/const_discriminant.rs
+++ b/src/test/ui/consts/const_discriminant.rs
@@ -25,6 +25,12 @@ enum SingleVariant {
 
 const TEST_V: Discriminant<SingleVariant> = discriminant(&SingleVariant::V);
 
+pub const TEST_VOID: () = {
+    // This is UB, but CTFE does not check validity so it does not detect this.
+    unsafe { std::mem::discriminant(&*(&() as *const () as *const Void)); };
+};
+
+
 fn main() {
     assert_eq!(TEST_A, TEST_A_OTHER);
     assert_eq!(TEST_A, discriminant(black_box(&Test::A(17))));

From 9ec88626eac5e3e7c5fd719135545f1ac31fab8b Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 14 Nov 2021 19:03:32 -0500
Subject: [PATCH 7/7] expand comment

---
 src/test/ui/consts/const_discriminant.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/test/ui/consts/const_discriminant.rs b/src/test/ui/consts/const_discriminant.rs
index a9c0217ae2421..f623c5101f4cd 100644
--- a/src/test/ui/consts/const_discriminant.rs
+++ b/src/test/ui/consts/const_discriminant.rs
@@ -27,6 +27,7 @@ const TEST_V: Discriminant<SingleVariant> = discriminant(&SingleVariant::V);
 
 pub const TEST_VOID: () = {
     // This is UB, but CTFE does not check validity so it does not detect this.
+    // This is a regression test for https://github.com/rust-lang/rust/issues/89765.
     unsafe { std::mem::discriminant(&*(&() as *const () as *const Void)); };
 };