]> git.lizzy.rs Git - rust.git/commitdiff
Only memoize const fn calls during const eval
authorOliver Scherer <github35764891676564198441@oli-obk.de>
Fri, 29 Nov 2019 10:57:17 +0000 (11:57 +0100)
committerOliver Scherer <github35764891676564198441@oli-obk.de>
Fri, 29 Nov 2019 10:57:17 +0000 (11:57 +0100)
Miri and other engines may want to execute the function in order to detect UB inside of them.

src/librustc_mir/const_eval.rs
src/librustc_mir/interpret/terminator.rs

index 0967b25788557c009bfe5d9d18bb461cd21dedac..005d3b217eb3de22d086ab20cf9d62b0a5edca14 100644 (file)
@@ -336,6 +336,20 @@ fn find_fn(
         _unwind: Option<mir::BasicBlock> // unwinding is not supported in consts
     ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
         debug!("eval_fn_call: {:?}", instance);
+
+        // If this function is a `const fn` then as an optimization we can query this
+        // evaluation immediately.
+        //
+        // For the moment we only do this for functions which take no arguments
+        // (or all arguments are ZSTs) so that we don't memoize too much.
+        if ecx.tcx.is_const_fn_raw(instance.def.def_id()) &&
+            args.iter().all(|a| a.layout.is_zst())
+        {
+            let gid = GlobalId { instance, promoted: None };
+            ecx.eval_const_fn_call(gid, ret)?;
+            return Ok(None);
+        }
+
         // 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 do a stability-
index 7285836d1c3182d99bf97e1b18a0253e16ec99d9..ed037570d6db89624b74b5cc9fffcd8a3ff57236 100644 (file)
@@ -284,18 +284,6 @@ fn eval_fn_call(
             ty::InstanceDef::DropGlue(..) |
             ty::InstanceDef::CloneShim(..) |
             ty::InstanceDef::Item(_) => {
-                // If this function is a `const fn` then as an optimization we can query this
-                // evaluation immediately.
-                //
-                // For the moment we only do this for functions which take no arguments
-                // (or all arguments are ZSTs) so that we don't memoize too much.
-                if self.tcx.is_const_fn_raw(instance.def.def_id()) &&
-                   args.iter().all(|a| a.layout.is_zst())
-                {
-                    let gid = GlobalId { instance, promoted: None };
-                    return self.eval_const_fn_call(gid, ret);
-                }
-
                 // We need MIR for this fn
                 let body = match M::find_fn(self, instance, args, ret, unwind)? {
                     Some(body) => body,
@@ -463,7 +451,7 @@ fn eval_fn_call(
 
     /// Evaluate a const function where all arguments (if any) are zero-sized types.
     /// The evaluation is memoized thanks to the query system.
-    fn eval_const_fn_call(
+    pub (crate) fn eval_const_fn_call(
         &mut self,
         gid: GlobalId<'tcx>,
         ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,