-
Notifications
You must be signed in to change notification settings - Fork 13.3k
rustc infinite loop: warning: Constant evaluating a complex constant, this might take some time #50637
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
This was decided in general over in rust-lang/rfcs#2344 (comment) @oli-obk Would be be feasible to catch some simple cases of "this definitely won't finish"? |
Existing control-flow analysis gives a warning about unreachable code following a |
uuuuh... Reaching that warning is a bug in my book. The first error should have cause this expression from never being evaluated. That said,
Oh yea, there's a super easy trick for doing that. The moment we emit the warning, we hash the state of the const evaluator and place it into a HashSet. Then, every (n?) step(s) from then on, we do the same. If we ever encounter the same hash again, we're 100% in an infinite loop, because const eval is deterministic and thus reaching the same state will mean we'll just reach it again soonish. |
Definitely a bug. Not P-high, but we ought to fix. Marking as P-medium. My ideal scenario here is that @oli-obk writes up mentoring instructions and adds the appropriate labels, because this seems like a nice bug for someone looking to learn something about miri. |
As a first step, we should implement #49980, which turns the unconditional warning into a lint. Then, in order to actually detect true recursions and abort for them:
This will take riddiculous amounts of memory and computation time, but since we only start doing this once we hit a certain counter limit, this should be fine. If not, we can just increase the limit. Once we have hit the limit we also need to set a flag so while we will now do the hashing at every step, the lint should only show up every 1M steps (or whatever the setting is). |
This test relies on the fact that restrictions on expressions in `const fn` do not apply when computing array lengths. It is more difficult to statically analyze than the simple `loop{}` mentioned in rust-lang#50637. This test should be updated to ignore the warning after rust-lang#49980 is resolved.
Infinite loop detection for const evaluation Resolves #50637. An `EvalContext` stores the transient state (stack, heap, etc.) of the MIRI virtual machine while it executing code. As long as MIRI only executes pure functions, we can detect if a program is in a state where it will never terminate by periodically taking a "snapshot" of this transient state and comparing it to previous ones. If any two states are exactly equal, the machine must be in an infinite loop. Instead of fully cloning a snapshot every time the detector is run, we store a snapshot's hash. Only when a hash collision occurs do we fully clone the interpreter state. Future snapshots which cause a collision will be compared against this clone, causing the interpreter to abort if they are equal. At the moment, snapshots are not taken until MIRI has progressed a certain amount. After this threshold, snapshots are taken every `DETECTOR_SNAPSHOT_PERIOD` steps. This means that an infinite loop with period `P` will be detected after a maximum of `2 * P * DETECTOR_SNAPSHOT_PERIOD` interpreter steps. The factor of 2 arises because we only clone a snapshot after it causes a hash collision.
Not sure if this is really a bug, but I tried searching and couldn't find any hits on the warning message. Feel free to close the issue if this is intended/expected behaviour.
Input:
Output:
At this point the rustc process hangs seemingly forever while consuming 100% CPU.
I'm on commit c166b03.
The text was updated successfully, but these errors were encountered: