diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 9d5dbe3564e..3afc7290ca9 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -636,28 +636,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { self.check_binary_op(*op, left, right, source_info, place_layout, overflow_check)?; } - // Work around: avoid ICE in miri. FIXME(wesleywiser) - // The Miri engine ICEs when taking a reference to an uninitialized unsized - // local. There's nothing it can do here: taking a reference needs an allocation - // which needs to know the size. Normally that's okay as during execution - // (e.g. for CTFE) it can never happen. But here in const_prop - // unknown data is uninitialized, so if e.g. a function argument is unsized - // and has a reference taken, we get an ICE. + // Do not try creating references (#67862) Rvalue::Ref(_, _, place_ref) => { - trace!("checking Ref({:?})", place_ref); + trace!("skipping Ref({:?})", place_ref); - if let Some(local) = place_ref.as_local() { - let alive = if let LocalValue::Live(_) = self.ecx.frame().locals[local].value { - true - } else { - false - }; - - if !alive { - trace!("skipping Ref({:?}) to uninitialized local", place); - return None; - } - } + return None; } _ => {} diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs index 5808a8be176..ca539fb7462 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.rs +++ b/src/test/mir-opt/const_prop/ref_deref_project.rs @@ -1,5 +1,5 @@ fn main() { - *(&(4, 5).1); + *(&(4, 5).1); // This does not currently propagate (#67862) } // END RUST SOURCE @@ -35,7 +35,7 @@ fn main() { // ... // _4 = const main::promoted[0]; // _2 = &((*_4).1: i32); -// _1 = const 5i32; +// _1 = (*_2); // ... // } // END rustc.main.ConstProp.after.mir diff --git a/src/test/ui/consts/issue-67529.rs b/src/test/ui/consts/issue-67529.rs new file mode 100644 index 00000000000..df4bc668bee --- /dev/null +++ b/src/test/ui/consts/issue-67529.rs @@ -0,0 +1,11 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +struct Baz { + a: T +} + +fn main() { + let d : Baz<[i32; 4]> = Baz { a: [1,2,3,4] }; + assert_eq!([1, 2, 3, 4], d.a); +} diff --git a/src/test/ui/consts/issue-67640.rs b/src/test/ui/consts/issue-67640.rs new file mode 100644 index 00000000000..bc0ee8d386f --- /dev/null +++ b/src/test/ui/consts/issue-67640.rs @@ -0,0 +1,24 @@ +// compile-flags: -Z mir-opt-level=3 +// run-pass + +struct X { + x: isize +} + +fn f1(a: &mut X, b: &mut isize, c: isize) -> isize { + let r = a.x + *b + c; + a.x = 0; + *b = 10; + return r; +} + +fn f2(a: isize, f: F) -> isize where F: FnOnce(isize) { f(1); return a; } + +pub fn main() { + let mut a = X {x: 1}; + let mut b = 2; + let c = 3; + assert_eq!(f1(&mut a, &mut b, c), 6); + assert_eq!(a.x, 0); + assert_eq!(f2(a.x, |_| a.x = 50), 0); +} diff --git a/src/test/ui/consts/issue-67641.rs b/src/test/ui/consts/issue-67641.rs new file mode 100644 index 00000000000..f50fba287a2 --- /dev/null +++ b/src/test/ui/consts/issue-67641.rs @@ -0,0 +1,24 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +use std::cell::Cell; + +#[derive(Debug)] +struct B<'a> { + a: [Cell>>; 2] +} + +impl<'a> B<'a> { + fn new() -> B<'a> { + B { a: [Cell::new(None), Cell::new(None)] } + } +} + +fn f() { + let b2 = B::new(); + b2.a[0].set(Some(&b2)); +} + +fn main() { + f(); +} diff --git a/src/test/ui/consts/issue-67862.rs b/src/test/ui/consts/issue-67862.rs new file mode 100644 index 00000000000..84f72154d26 --- /dev/null +++ b/src/test/ui/consts/issue-67862.rs @@ -0,0 +1,18 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +fn e220() -> (i64, i64) { + #[inline(never)] + fn get_displacement() -> [i64; 2] { + [139776, 963904] + } + + let res = get_displacement(); + match (&res[0], &res[1]) { + (arg0, arg1) => (*arg0, *arg1), + } +} + +fn main() { + assert_eq!(e220(), (139776, 963904)); +}