about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2019-01-18 13:31:05 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2019-01-18 13:31:05 +0100
commitefda6816bd29beea2702c7c3f76a252a405e60ae (patch)
treec00141747fd2000905b27e2aa2da3793232e6152 /src
parent1dc4e417fa2a73d5ffa24428df6b7d4dbbf41f4a (diff)
downloadrust-efda6816bd29beea2702c7c3f76a252a405e60ae.tar.gz
rust-efda6816bd29beea2702c7c3f76a252a405e60ae.zip
Allow evaluating trivial drop glue in constants
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/const_eval.rs29
-rw-r--r--src/test/ui/consts/drop_none.rs13
2 files changed, 29 insertions, 13 deletions
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index f5f40481679..f6ecf7c9436 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -391,19 +391,22 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
         ret: Option<mir::BasicBlock>,
     ) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>> {
         debug!("eval_fn_call: {:?}", instance);
-        // Execution might have wandered off into other crates, so we cannot to a stability-
-        // sensitive check here.  But we can at least rule out functions that are not const
-        // at all.
-        if !ecx.tcx.is_const_fn_raw(instance.def_id()) {
-            // Some functions we support even if they are non-const -- but avoid testing
-            // that for const fn!  We certainly do *not* want to actually call the fn
-            // though, so be sure we return here.
-            return if ecx.hook_fn(instance, args, dest)? {
-                ecx.goto_block(ret)?; // fully evaluated and done
-                Ok(None)
-            } else {
-                err!(MachineError(format!("calling non-const function `{}`", instance)))
-            };
+        // Only check non-glue functions
+        if let ty::InstanceDef::Item(def_id) = instance.def {
+            // Execution might have wandered off into other crates, so we cannot to a stability-
+            // sensitive check here.  But we can at least rule out functions that are not const
+            // at all.
+            if !ecx.tcx.is_const_fn_raw(def_id) {
+                // Some functions we support even if they are non-const -- but avoid testing
+                // that for const fn!  We certainly do *not* want to actually call the fn
+                // though, so be sure we return here.
+                return if ecx.hook_fn(instance, args, dest)? {
+                    ecx.goto_block(ret)?; // fully evaluated and done
+                    Ok(None)
+                } else {
+                    err!(MachineError(format!("calling non-const function `{}`", instance)))
+                };
+            }
         }
         // This is a const fn. Call it.
         Ok(Some(match ecx.load_mir(instance.def) {
diff --git a/src/test/ui/consts/drop_none.rs b/src/test/ui/consts/drop_none.rs
new file mode 100644
index 00000000000..86a197ffb99
--- /dev/null
+++ b/src/test/ui/consts/drop_none.rs
@@ -0,0 +1,13 @@
+// compile-pass
+#![allow(dead_code)]
+struct A;
+impl Drop for A {
+    fn drop(&mut self) {}
+}
+
+const FOO: Option<A> = None;
+
+const BAR: () = (FOO, ()).1;
+
+
+fn main() {}