Avoid infinite recursion when trying to build valtrees for self-referential consts#158553
Conversation
|
rustbot has assigned @petrochenkov. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
r? ctfe |
|
Failed to set assignee to
|
|
r? const-eval |
|
Failed to set assignee to
|
|
r? @RalfJung for review or further reassignment |
|
|
There was a problem hiding this comment.
I don't think this actually solves the issue. It solves it for small loops, but if the chain is deep enough, we'll just end up in the same situation again:
#[derive(PartialEq)]
struct Thing(&'static Thing);
static A: Thing = Thing(&B);
static B: Thing = Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&Thing(&A))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
const C: &Thing = &A;
fn main() {
if let C = C {}
//~^ ERROR constant C cannot be used as pattern
}or possibly a few more nested ones.
Or maybe the following works?
#[derive(PartialEq, Copy, Clone)]
struct Thing(&'static Thing);
static A: Thing = Thing(B[0]);
const N: usize = 100_000_000;
static B: [&Thing; N] = {
let mut x = [&Thing(&A); N];
let mut i = 0;
while i < N - 1 {
x[i] = &x[i + 1];
i += 1;
}
x
};
const C: &Thing = A;
fn main() {
if let C = C {}
//~^ ERROR constant C cannot be used as pattern
}|
Reminder, once the PR becomes ready for a review, use |
|
The second example overflowed the stack, even with N = 8000, so I wrapped the recursion in I tested it up to N = 50000 without issue, but anything past that took far too long to get any results. The first case also errors properly, and when I tried increasing the nesting to several thousand, both the current nightly and this stage1 crash during name resolution. I added a test for the second case which sets @rustbot ready |
🤣 |
another alternative is to do no tracking at all and just use the recursion limit. But if it works well, let's go with this for now. @bors try @rust-timer queue let's make sure this common code path doesn't regress too much |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Avoid infinite recursion when trying to build valtrees for self-referential consts
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (5da228f): comparison URL. Overall result: no relevant changes - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countThis perf run didn't have relevant results for this metric. Max RSS (memory usage)Results (primary -0.6%, secondary 2.2%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary -2.5%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeResults (secondary 0.0%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Bootstrap: 491.018s -> 494.091s (0.63%) |
|
@bors r+ rollup |
Avoid infinite recursion when trying to build valtrees for self-referential consts This PR adds cycle detection to `const_to_valtree_inner` by using a tricolor DFS, so self-referential statics in pats don't cause valtree construction to recurse infinitely. Instead, we now return a new `ValTreeCreationError::CyclicConst`, similar to the current `InvalidConst` and `NodesOverflow` variants. fixes rust-lang#144719
Rollup of 13 pull requests Successful merges: - #158478 (Use correct typing mode in mir building for the next solver) - #158796 (Distinguish null reference production from null pointer dereference in UB checks) - #158821 (add regression test for late-bound type method probe ICE) - #158245 (Update the rustc_perf submodule) - #158346 (Prevent rustdoc auto-trait ICEs with `-Znext-solver=globally`) - #158536 (Instatiate binder instead of skipping when suggesting function arg error) - #158553 (Avoid infinite recursion when trying to build valtrees for self-referential consts) - #158679 (Document blocking guarantees for `std::sync`) - #158826 (Reorganize `tests/ui/issues` [19/N]) - #158860 (Delete `impl_def_id` field from `ImplHeader`) - #158867 (rewrite `Align::max_for_target` in a more obvious way) - #158878 (borrowck: Inline `free_region_constraint_info()` to simplify the code) - #158881 (Update mdbook to 0.5.4)
Rollup merge of #158553 - sjwang05:issue-144719, r=oli-obk Avoid infinite recursion when trying to build valtrees for self-referential consts This PR adds cycle detection to `const_to_valtree_inner` by using a tricolor DFS, so self-referential statics in pats don't cause valtree construction to recurse infinitely. Instead, we now return a new `ValTreeCreationError::CyclicConst`, similar to the current `InvalidConst` and `NodesOverflow` variants. fixes #144719
View all comments
This PR adds cycle detection to
const_to_valtree_innerby using a tricolor DFS, so self-referential statics in pats don't cause valtree construction to recurse infinitely. Instead, we now return a newValTreeCreationError::CyclicConst, similar to the currentInvalidConstandNodesOverflowvariants.fixes #144719