about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChristoph Schmidler <c.schmidler@gmail.com>2020-01-21 16:46:07 +0100
committerChristoph Schmidler <c.schmidler@gmail.com>2020-03-05 08:09:52 +0100
commitc94c74e2d936213cabcbb9675f81007ac7c3b78a (patch)
tree15189209ddd04691f9c7053e5c1f691a35b6121f
parent288e142737af75007ef973c037cd4ded87d7e510 (diff)
downloadrust-c94c74e2d936213cabcbb9675f81007ac7c3b78a.tar.gz
rust-c94c74e2d936213cabcbb9675f81007ac7c3b78a.zip
Opt out of CTFE if the 'const_eval_limit' is set to 0
-rw-r--r--src/doc/unstable-book/src/language-features/const-eval-limit.md4
-rw-r--r--src/librustc_mir/const_eval/eval_queries.rs4
-rw-r--r--src/librustc_mir/const_eval/machine.rs18
-rw-r--r--src/test/ui/consts/const_limit/const_eval_limit_reached.rs2
-rw-r--r--src/test/ui/consts/const_limit/const_eval_limit_reached.stderr6
-rw-r--r--src/test/ui/consts/const_limit/feature-gate-const_eval_limit.stderr2
6 files changed, 26 insertions, 10 deletions
diff --git a/src/doc/unstable-book/src/language-features/const-eval-limit.md b/src/doc/unstable-book/src/language-features/const-eval-limit.md
index d1442d866dc..df68e83bcac 100644
--- a/src/doc/unstable-book/src/language-features/const-eval-limit.md
+++ b/src/doc/unstable-book/src/language-features/const-eval-limit.md
@@ -2,6 +2,6 @@
 
 The tracking issue for this feature is: [#67217]
 
-[#57563]: https://github.com/rust-lang/rust/issues/67217
+[#67217]: https://github.com/rust-lang/rust/issues/67217
 
-The `const_eval_limit` allows someone to limit the evaluation steps the CTFE undertakes to evaluate a `const fn`.
\ No newline at end of file
+The `const_eval_limit` allows someone to limit the evaluation steps the CTFE undertakes to evaluate a `const fn`.
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index 4d5464f774f..1bf748e66e2 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -89,7 +89,7 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>(
     InterpCx::new(
         tcx.at(span),
         param_env,
-        CompileTimeInterpreter::new(),
+        CompileTimeInterpreter::new(*tcx.sess.const_eval_limit.get()),
         MemoryExtra { can_access_statics },
     )
 }
@@ -297,7 +297,7 @@ pub fn const_eval_raw_provider<'tcx>(
     let mut ecx = InterpCx::new(
         tcx.at(span),
         key.param_env,
-        CompileTimeInterpreter::new(),
+        CompileTimeInterpreter::new(*tcx.sess.const_eval_limit.get()),
         MemoryExtra { can_access_statics: is_static },
     );
 
diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs
index 25727b75faf..ed802983468 100644
--- a/src/librustc_mir/const_eval/machine.rs
+++ b/src/librustc_mir/const_eval/machine.rs
@@ -3,6 +3,7 @@ use rustc::ty::layout::HasTyCtxt;
 use rustc::ty::{self, Ty};
 use std::borrow::{Borrow, Cow};
 use std::collections::hash_map::Entry;
+use std::convert::TryFrom;
 use std::hash::Hash;
 
 use rustc_data_structures::fx::FxHashMap;
@@ -85,9 +86,6 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
     }
 }
 
-/// Number of steps until the detector even starts doing anything.
-/// Also, a warning is shown to the user when this number is reached.
-const STEPS_UNTIL_DETECTOR_ENABLED: isize = 1_000_000;
 /// The number of steps between loop detector snapshots.
 /// Should be a power of two for performance reasons.
 const DETECTOR_SNAPSHOT_PERIOD: isize = 256;
@@ -100,6 +98,8 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
     /// detector period.
     pub(super) steps_since_detector_enabled: isize,
 
+    pub(super) is_detector_enabled: bool,
+
     /// Extra state to detect loops.
     pub(super) loop_detector: snapshot::InfiniteLoopDetector<'mir, 'tcx>,
 }
@@ -111,10 +111,14 @@ pub struct MemoryExtra {
 }
 
 impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
-    pub(super) fn new() -> Self {
+    pub(super) fn new(const_eval_limit: usize) -> Self {
+        let steps_until_detector_enabled =
+            isize::try_from(const_eval_limit).unwrap_or(std::isize::MAX);
+
         CompileTimeInterpreter {
             loop_detector: Default::default(),
-            steps_since_detector_enabled: -STEPS_UNTIL_DETECTOR_ENABLED,
+            steps_since_detector_enabled: -steps_until_detector_enabled,
+            is_detector_enabled: const_eval_limit != 0,
         }
     }
 }
@@ -343,6 +347,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
     }
 
     fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
+        if !ecx.machine.is_detector_enabled {
+            return Ok(());
+        }
+
         {
             let steps = &mut ecx.machine.steps_since_detector_enabled;
 
diff --git a/src/test/ui/consts/const_limit/const_eval_limit_reached.rs b/src/test/ui/consts/const_limit/const_eval_limit_reached.rs
index 86570c240e5..1e146d447fa 100644
--- a/src/test/ui/consts/const_limit/const_eval_limit_reached.rs
+++ b/src/test/ui/consts/const_limit/const_eval_limit_reached.rs
@@ -1,8 +1,10 @@
+// only-x86_64
 // check-pass
 #![feature(const_eval_limit)]
 #![const_eval_limit="2"]
 
 const CONSTANT: usize = limit();
+//~^ WARNING Constant evaluating a complex constant, this might take some time
 
 fn main() {
     assert_eq!(CONSTANT, 1764);
diff --git a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr
new file mode 100644
index 00000000000..8301dff6005
--- /dev/null
+++ b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr
@@ -0,0 +1,6 @@
+warning: Constant evaluating a complex constant, this might take some time
+  --> $DIR/const_eval_limit_reached.rs:6:1
+   |
+LL | const CONSTANT: usize = limit();
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/src/test/ui/consts/const_limit/feature-gate-const_eval_limit.stderr b/src/test/ui/consts/const_limit/feature-gate-const_eval_limit.stderr
index 790ba2483a1..5bd29c7dfd2 100644
--- a/src/test/ui/consts/const_limit/feature-gate-const_eval_limit.stderr
+++ b/src/test/ui/consts/const_limit/feature-gate-const_eval_limit.stderr
@@ -4,7 +4,7 @@ error[E0658]: the `#[const_eval_limit]` attribute is an experimental feature
 LL | #![const_eval_limit="42"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/67217
+   = note: see issue #67217 <https://github.com/rust-lang/rust/issues/67217> for more information
    = help: add `#![feature(const_eval_limit)]` to the crate attributes to enable
 
 error: aborting due to previous error