about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/infer/canonical/canonicalizer.rs2
-rw-r--r--src/librustc/lint/levels.rs6
-rw-r--r--src/librustc_mir/transform/const_prop.rs26
-rw-r--r--src/librustc_mir/transform/simplify.rs76
-rw-r--r--src/librustc_resolve/error_codes.rs2
-rw-r--r--src/libstd/keyword_docs.rs67
-rw-r--r--src/test/incremental/const-generics/issue-61338.rs14
-rw-r--r--src/test/incremental/const-generics/issue-61516.rs16
-rw-r--r--src/test/incremental/const-generics/issue-62536.rs12
-rw-r--r--src/test/incremental/const-generics/issue-64087.rs11
-rw-r--r--src/test/incremental/const-generics/issue-65623.rs14
-rw-r--r--src/test/incremental/hashes/for_loops.rs2
-rw-r--r--src/test/incremental/hashes/let_expressions.rs8
-rw-r--r--src/test/incremental/hashes/loop_expressions.rs2
-rw-r--r--src/test/incremental/hashes/while_let_loops.rs2
-rw-r--r--src/test/incremental/hashes/while_loops.rs2
-rw-r--r--src/test/mir-opt/simplify-locals-removes-unused-consts.rs89
-rw-r--r--src/test/mir-opt/slice-drop-shim.rs4
18 files changed, 298 insertions, 57 deletions
diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs
index b9474f869ee..e69719806a8 100644
--- a/src/librustc/infer/canonical/canonicalizer.rs
+++ b/src/librustc/infer/canonical/canonicalizer.rs
@@ -701,7 +701,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
             self.tcx().mk_const(
                 ty::Const {
                     val: ConstValue::Infer(InferConst::Canonical(self.binder_index, var.into())),
-                    ty: const_var.ty,
+                    ty: self.fold_ty(const_var.ty),
                 }
             )
         }
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 60b1b192d10..8ed06cbdc76 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -202,11 +202,7 @@ impl<'a> LintLevelsBuilder<'a> {
             let meta = unwrap_or!(attr.meta(), continue);
             attr::mark_used(attr);
 
-            let mut metas = if let Some(metas) = meta.meta_item_list() {
-                metas
-            } else {
-                continue;
-            };
+            let mut metas = unwrap_or!(meta.meta_item_list(), continue);
 
             if metas.is_empty() {
                 // FIXME (#55112): issue unused-attributes lint for `#[level()]`
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 780b49cd9db..108c6c9786b 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -431,7 +431,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         place_layout: TyLayout<'tcx>,
         source_info: SourceInfo,
         place: &Place<'tcx>,
-    ) -> Option<Const<'tcx>> {
+    ) -> Option<()> {
         let span = source_info.span;
 
         let overflow_check = self.tcx.sess.overflow_checks();
@@ -540,20 +540,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 }
             }
 
-            // Work around: avoid extra unnecessary locals. FIXME(wesleywiser)
-            // Const eval will turn this into a `const Scalar(<ZST>)` that
-            // `SimplifyLocals` doesn't know it can remove.
-            Rvalue::Aggregate(_, operands) if operands.len() == 0 => {
-                return None;
-            }
-
             _ => { }
         }
 
         self.use_ecx(source_info, |this| {
             trace!("calling eval_rvalue_into_place(rvalue = {:?}, place = {:?})", rvalue, place);
             this.ecx.eval_rvalue_into_place(rvalue, place)?;
-            this.ecx.eval_place_to_op(place, Some(place_layout))
+            Ok(())
         })
     }
 
@@ -717,16 +710,15 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
                     base: PlaceBase::Local(local),
                     projection: box [],
                 } = *place {
-                    if let Some(value) = self.const_prop(rval,
-                                                         place_layout,
-                                                         statement.source_info,
-                                                         place) {
-                        trace!("checking whether {:?} can be stored to {:?}", value, local);
+                    let source = statement.source_info;
+                    if let Some(()) = self.const_prop(rval, place_layout, source, place) {
                         if self.can_const_prop[local] {
-                            trace!("stored {:?} to {:?}", value, local);
-                            assert_eq!(self.get_const(local), Some(value));
+                            trace!("propagated into {:?}", local);
 
                             if self.should_const_prop() {
+                                let value =
+                                    self.get_const(local).expect("local was dead/uninitialized");
+                                trace!("replacing {:?} with {:?}", rval, value);
                                 self.replace_with_const(
                                     rval,
                                     value,
@@ -734,7 +726,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
                                 );
                             }
                         } else {
-                            trace!("can't propagate {:?} to {:?}", value, local);
+                            trace!("can't propagate into {:?}", local);
                             self.remove_const(local);
                         }
                     }
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index 606c1a3a1cc..e41b4678dbd 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -31,7 +31,7 @@ use rustc_index::bit_set::BitSet;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc::ty::TyCtxt;
 use rustc::mir::*;
-use rustc::mir::visit::{MutVisitor, Visitor, PlaceContext};
+use rustc::mir::visit::{MutVisitor, Visitor, PlaceContext, MutatingUseContext};
 use rustc::session::config::DebugInfo;
 use std::borrow::Cow;
 use crate::transform::{MirPass, MirSource};
@@ -293,23 +293,31 @@ pub fn remove_dead_blocks(body: &mut Body<'_>) {
 pub struct SimplifyLocals;
 
 impl<'tcx> MirPass<'tcx> for SimplifyLocals {
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
-        let mut marker = DeclMarker { locals: BitSet::new_empty(body.local_decls.len()) };
-        marker.visit_body(body);
-        // Return pointer and arguments are always live
-        marker.locals.insert(RETURN_PLACE);
-        for arg in body.args_iter() {
-            marker.locals.insert(arg);
-        }
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
+        trace!("running SimplifyLocals on {:?}", source);
+        let locals = {
+            let mut marker = DeclMarker {
+                locals: BitSet::new_empty(body.local_decls.len()),
+                body,
+            };
+            marker.visit_body(body);
+            // Return pointer and arguments are always live
+            marker.locals.insert(RETURN_PLACE);
+            for arg in body.args_iter() {
+                marker.locals.insert(arg);
+            }
 
-        // We may need to keep dead user variables live for debuginfo.
-        if tcx.sess.opts.debuginfo == DebugInfo::Full {
-            for local in body.vars_iter() {
-                marker.locals.insert(local);
+            // We may need to keep dead user variables live for debuginfo.
+            if tcx.sess.opts.debuginfo == DebugInfo::Full {
+                for local in body.vars_iter() {
+                    marker.locals.insert(local);
+                }
             }
-        }
 
-        let map = make_local_map(&mut body.local_decls, marker.locals);
+            marker.locals
+        };
+
+        let map = make_local_map(&mut body.local_decls, locals);
         // Update references to all vars and tmps now
         LocalUpdater { map }.visit_body(body);
         body.local_decls.shrink_to_fit();
@@ -334,18 +342,35 @@ fn make_local_map<V>(
     map
 }
 
-struct DeclMarker {
+struct DeclMarker<'a, 'tcx> {
     pub locals: BitSet<Local>,
+    pub body: &'a Body<'tcx>,
 }
 
-impl<'tcx> Visitor<'tcx> for DeclMarker {
-    fn visit_local(&mut self, local: &Local, ctx: PlaceContext, _: Location) {
+impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> {
+    fn visit_local(&mut self, local: &Local, ctx: PlaceContext, location: Location) {
         // Ignore storage markers altogether, they get removed along with their otherwise unused
         // decls.
         // FIXME: Extend this to all non-uses.
-        if !ctx.is_storage_marker() {
-            self.locals.insert(*local);
+        if ctx.is_storage_marker() {
+            return;
         }
+
+        // Ignore stores of constants because `ConstProp` and `CopyProp` can remove uses of many
+        // of these locals. However, if the local is still needed, then it will be referenced in
+        // another place and we'll mark it as being used there.
+        if ctx == PlaceContext::MutatingUse(MutatingUseContext::Store) {
+            let stmt =
+                &self.body.basic_blocks()[location.block].statements[location.statement_index];
+            if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(c)))) = &stmt.kind {
+                if p.as_local().is_some() {
+                    trace!("skipping store of const value {:?} to {:?}", c, local);
+                    return;
+                }
+            }
+        }
+
+        self.locals.insert(*local);
     }
 }
 
@@ -357,9 +382,16 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater {
     fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) {
         // Remove unnecessary StorageLive and StorageDead annotations.
         data.statements.retain(|stmt| {
-            match stmt.kind {
+            match &stmt.kind {
                 StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => {
-                    self.map[l].is_some()
+                    self.map[*l].is_some()
+                }
+                StatementKind::Assign(box (place, _)) => {
+                    if let Some(local) = place.as_local() {
+                        self.map[local].is_some()
+                    } else {
+                        true
+                    }
                 }
                 _ => true
             }
diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs
index cd6189c681d..b82cba8c83d 100644
--- a/src/librustc_resolve/error_codes.rs
+++ b/src/librustc_resolve/error_codes.rs
@@ -1682,7 +1682,7 @@ enum Wizard {
 }
 
 trait Isengard {
-    fn wizard(w: Wizard) { // error!
+    fn wizard(w: Wizard) { // ok!
         match w {
             Wizard::Saruman => {
                 // do something
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index a8dfe924fdf..ab8a55660cb 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -33,9 +33,72 @@ mod as_keyword { }
 //
 /// Exit early from a loop.
 ///
-/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+/// When `break` is encountered, execution of the associated loop body is
+/// immediately terminated.
+///
+/// ```rust
+/// let mut last = 0;
+///
+/// for x in 1..100 {
+///     if x > 12 {
+///         break;
+///     }
+///     last = x;
+/// }
+///
+/// assert_eq!(last, 12);
+/// println!("{}", last);
+/// ```
+///
+/// A break expression is normally associated with the innermost loop enclosing the
+/// `break` but a label can be used to specify which enclosing loop is affected.
+///
+///```rust
+/// 'outer: for i in 1..=5 {
+///     println!("outer iteration (i): {}", i);
+///
+///     'inner: for j in 1..=200 {
+///         println!("    inner iteration (j): {}", j);
+///         if j >= 3 {
+///             // breaks from inner loop, let's outer loop continue.
+///             break;
+///         }
+///         if i >= 2 {
+///             // breaks from outer loop, and directly to "Bye".
+///             break 'outer;
+///         }
+///     }
+/// }
+/// println!("Bye.");
+///```
+///
+/// When associated with `loop`, a break expression may be used to return a value from that loop.
+/// This is only valid with `loop` and not with any other type of loop.
+/// If no value is specified, `break;` returns `()`.
+/// Every `break` within a loop must return the same type.
+///
+/// ```rust
+/// let (mut a, mut b) = (1, 1);
+/// let result = loop {
+///     if b > 10 {
+///         break b;
+///     }
+///     let c = a + b;
+///     a = b;
+///     b = c;
+/// };
+/// // first number in Fibonacci sequence over 10:
+/// assert_eq!(result, 13);
+/// println!("{}", result);
+/// ```
+///
+/// For more details consult the [Reference on "break expression"] and the [Reference on "break and
+/// loop values"].
+///
+/// [Reference on "break expression"]: ../reference/expressions/loop-expr.html#break-expressions
+/// [Reference on "break and loop values"]:
+/// ../reference/expressions/loop-expr.html#break-and-loop-values
 ///
-/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
 mod break_keyword { }
 
 #[doc(keyword = "const")]
diff --git a/src/test/incremental/const-generics/issue-61338.rs b/src/test/incremental/const-generics/issue-61338.rs
new file mode 100644
index 00000000000..00b3b29698b
--- /dev/null
+++ b/src/test/incremental/const-generics/issue-61338.rs
@@ -0,0 +1,14 @@
+// revisions:rpass1
+
+#![feature(const_generics)]
+
+struct Struct<T>(T);
+
+impl<T, const N: usize> Struct<[T; N]> {
+    fn f() {}
+    fn g() { Self::f(); }
+}
+
+fn main() {
+    Struct::<[u32; 3]>::g();
+}
diff --git a/src/test/incremental/const-generics/issue-61516.rs b/src/test/incremental/const-generics/issue-61516.rs
new file mode 100644
index 00000000000..a7465b77267
--- /dev/null
+++ b/src/test/incremental/const-generics/issue-61516.rs
@@ -0,0 +1,16 @@
+// revisions:rpass1
+
+#![feature(const_generics)]
+
+struct FakeArray<T, const N: usize>(T);
+
+impl<T, const N: usize> FakeArray<T, { N }> {
+    fn len(&self) -> usize {
+        N
+    }
+}
+
+fn main() {
+    let fa = FakeArray::<u32, { 32 }>(1);
+    assert_eq!(fa.len(), 32);
+}
diff --git a/src/test/incremental/const-generics/issue-62536.rs b/src/test/incremental/const-generics/issue-62536.rs
new file mode 100644
index 00000000000..90e279bfc74
--- /dev/null
+++ b/src/test/incremental/const-generics/issue-62536.rs
@@ -0,0 +1,12 @@
+// revisions:cfail1
+#![feature(const_generics)]
+//[cfail1]~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+struct S<T, const N: usize>([T; N]);
+
+fn f<T, const N: usize>(x: T) -> S<T, {N}> { panic!() }
+
+fn main() {
+    f(0u8);
+    //[cfail1]~^ ERROR type annotations needed
+}
diff --git a/src/test/incremental/const-generics/issue-64087.rs b/src/test/incremental/const-generics/issue-64087.rs
new file mode 100644
index 00000000000..b3c12fbb6e8
--- /dev/null
+++ b/src/test/incremental/const-generics/issue-64087.rs
@@ -0,0 +1,11 @@
+// revisions:cfail1
+#![feature(const_generics)]
+//[cfail1]~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn combinator<T, const S: usize>() -> [T; S] {}
+//[cfail1]~^ ERROR mismatched types
+
+fn main() {
+    combinator().into_iter();
+    //[cfail1]~^ ERROR type annotations needed
+}
diff --git a/src/test/incremental/const-generics/issue-65623.rs b/src/test/incremental/const-generics/issue-65623.rs
new file mode 100644
index 00000000000..353e323e67b
--- /dev/null
+++ b/src/test/incremental/const-generics/issue-65623.rs
@@ -0,0 +1,14 @@
+// revisions:rpass1
+#![feature(const_generics)]
+
+pub struct Foo<T, const N: usize>([T; 0]);
+
+impl<T, const N: usize> Foo<T, {N}> {
+    pub fn new() -> Self {
+        Foo([])
+    }
+}
+
+fn main() {
+    let _: Foo<u32, 0> = Foo::new();
+}
diff --git a/src/test/incremental/hashes/for_loops.rs b/src/test/incremental/hashes/for_loops.rs
index 70820dfaea4..8e134ad14fc 100644
--- a/src/test/incremental/hashes/for_loops.rs
+++ b/src/test/incremental/hashes/for_loops.rs
@@ -25,7 +25,7 @@ pub fn change_loop_body() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_loop_body() {
     let mut _x = 0;
diff --git a/src/test/incremental/hashes/let_expressions.rs b/src/test/incremental/hashes/let_expressions.rs
index 68545b7daaa..4e8ba5a209d 100644
--- a/src/test/incremental/hashes/let_expressions.rs
+++ b/src/test/incremental/hashes/let_expressions.rs
@@ -22,7 +22,7 @@ pub fn change_name() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,mir_built,optimized_mir")]
+    except="HirBody,mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_name() {
     let _y = 2u64;
@@ -86,7 +86,7 @@ pub fn change_mutability_of_slot() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,typeck_tables_of,mir_built,optimized_mir")]
+    except="HirBody,typeck_tables_of,mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_mutability_of_slot() {
     let _x: u64 = 0;
@@ -182,7 +182,7 @@ pub fn add_initializer() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,typeck_tables_of,mir_built,optimized_mir")]
+    except="HirBody,typeck_tables_of,mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_initializer() {
     let _x: i16 = 3i16;
@@ -198,7 +198,7 @@ pub fn change_initializer() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,mir_built,optimized_mir")]
+    except="HirBody,mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_initializer() {
     let _x = 5u16;
diff --git a/src/test/incremental/hashes/loop_expressions.rs b/src/test/incremental/hashes/loop_expressions.rs
index a2222db4c59..ca85ee39e36 100644
--- a/src/test/incremental/hashes/loop_expressions.rs
+++ b/src/test/incremental/hashes/loop_expressions.rs
@@ -25,7 +25,7 @@ pub fn change_loop_body() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_loop_body() {
     let mut _x = 0;
diff --git a/src/test/incremental/hashes/while_let_loops.rs b/src/test/incremental/hashes/while_let_loops.rs
index da3c957741f..1e628d01919 100644
--- a/src/test/incremental/hashes/while_let_loops.rs
+++ b/src/test/incremental/hashes/while_let_loops.rs
@@ -25,7 +25,7 @@ pub fn change_loop_body() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_loop_body() {
     let mut _x = 0;
diff --git a/src/test/incremental/hashes/while_loops.rs b/src/test/incremental/hashes/while_loops.rs
index 3be42e7a4ee..295c2244879 100644
--- a/src/test/incremental/hashes/while_loops.rs
+++ b/src/test/incremental/hashes/while_loops.rs
@@ -25,7 +25,7 @@ pub fn change_loop_body() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_loop_body() {
     let mut _x = 0;
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts.rs b/src/test/mir-opt/simplify-locals-removes-unused-consts.rs
new file mode 100644
index 00000000000..6f03438ff72
--- /dev/null
+++ b/src/test/mir-opt/simplify-locals-removes-unused-consts.rs
@@ -0,0 +1,89 @@
+// compile-flags: -C overflow-checks=no
+
+fn use_zst(_: ((), ())) { }
+
+struct Temp {
+    x: u8
+}
+
+fn use_u8(_: u8) { }
+
+fn main() {
+    let ((), ()) = ((), ());
+    use_zst(((), ()));
+
+    use_u8((Temp { x : 40 }).x + 2);
+}
+
+// END RUST SOURCE
+
+// START rustc.main.SimplifyLocals.before.mir
+// let mut _0: ();
+// let mut _1: ((), ());
+// let mut _2: ();
+// let mut _3: ();
+// let _4: ();
+// let mut _5: ((), ());
+// let mut _6: ();
+// let mut _7: ();
+// let _8: ();
+// let mut _9: u8;
+// let mut _10: u8;
+// let mut _11: Temp;
+// scope 1 {
+// }
+// bb0: {
+//   StorageLive(_1);
+//   StorageLive(_2);
+//   _2 = const Scalar(<ZST>) : ();
+//   StorageLive(_3);
+//   _3 = const Scalar(<ZST>) : ();
+//   _1 = const Scalar(<ZST>) : ((), ());
+//   StorageDead(_3);
+//   StorageDead(_2);
+//   StorageDead(_1);
+//   StorageLive(_4);
+//   StorageLive(_6);
+//   _6 = const Scalar(<ZST>) : ();
+//   StorageLive(_7);
+//   _7 = const Scalar(<ZST>) : ();
+//   StorageDead(_7);
+//   StorageDead(_6);
+//   _4 = const use_zst(const Scalar(<ZST>) : ((), ())) -> bb1;
+// }
+// bb1: {
+//   StorageDead(_4);
+//   StorageLive(_8);
+//   StorageLive(_10);
+//   StorageLive(_11);
+//   _11 = const Scalar(0x28) : Temp;
+//   _10 = const 40u8;
+//   StorageDead(_10);
+//   _8 = const use_u8(const 42u8) -> bb2;
+// }
+// bb2: {
+//   StorageDead(_11);
+//   StorageDead(_8);
+//   return;
+// }
+// END rustc.main.SimplifyLocals.before.mir
+// START rustc.main.SimplifyLocals.after.mir
+// let mut _0: ();
+// let _1: ();
+// let _2: ();
+// scope 1 {
+// }
+// bb0: {
+//   StorageLive(_1);
+//   _1 = const use_zst(const Scalar(<ZST>) : ((), ())) -> bb1;
+// }
+// bb1: {
+//   StorageDead(_1);
+//   StorageLive(_2);
+//   _2 = const use_u8(const 42u8) -> bb2;
+// }
+// bb2: {
+//   StorageDead(_2);
+//   return;
+// }
+// END rustc.main.SimplifyLocals.after.mir
diff --git a/src/test/mir-opt/slice-drop-shim.rs b/src/test/mir-opt/slice-drop-shim.rs
index 754fad51b21..f270dec5fe2 100644
--- a/src/test/mir-opt/slice-drop-shim.rs
+++ b/src/test/mir-opt/slice-drop-shim.rs
@@ -1,5 +1,7 @@
+// compile-flags: -Zmir-opt-level=0
+
 fn main() {
-    std::ptr::drop_in_place::<[String]> as unsafe fn(_);
+    let _fn = std::ptr::drop_in_place::<[String]> as unsafe fn(_);
 }
 
 // END RUST SOURCE