Skip to content

Avoid infinite recursion when trying to build valtrees for self-referential consts#158553

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
sjwang05:issue-144719
Jul 7, 2026
Merged

Avoid infinite recursion when trying to build valtrees for self-referential consts#158553
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
sjwang05:issue-144719

Conversation

@sjwang05

@sjwang05 sjwang05 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

View all comments

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

@rustbot

rustbot commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 29, 2026
@rustbot

rustbot commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

r? @petrochenkov

rustbot has assigned @petrochenkov.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 17 candidates

@sjwang05 sjwang05 changed the title Avoid infinite recursion when building valtrees for self-referential consts Avoid infinite recursion when trying to build valtrees for self-referential consts Jun 29, 2026
@petrochenkov

Copy link
Copy Markdown
Contributor

r? ctfe

@rustbot

rustbot commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Failed to set assignee to ctfe: invalid assignee

Note: Only org members with at least the repository "read" role, users with write permissions, or people who have commented on the PR may be assigned.

@petrochenkov

Copy link
Copy Markdown
Contributor

r? const-eval

@rustbot

rustbot commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Failed to set assignee to const-eval: invalid assignee

Note: Only org members with at least the repository "read" role, users with write permissions, or people who have commented on the PR may be assigned.

@petrochenkov

Copy link
Copy Markdown
Contributor

r? @RalfJung for review or further reassignment

@rustbot rustbot assigned RalfJung and unassigned petrochenkov Jun 29, 2026
@rustbot

rustbot commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

RalfJung is not on the review rotation at the moment.
They may take a while to respond.

@RalfJung

Copy link
Copy Markdown
Member

r? @oli-obk
or maybe @lcnr ?

@rustbot rustbot assigned oli-obk and unassigned RalfJung Jun 29, 2026

@oli-obk oli-obk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
}

View changes since this review

Comment thread compiler/rustc_const_eval/src/const_eval/valtrees.rs Outdated
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 2, 2026
@rustbot

rustbot commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@sjwang05

sjwang05 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

The second example overflowed the stack, even with N = 8000, so I wrapped the recursion in ensure_sufficient_stack, which seems to have solved the issue, though I'm not sure if that's the best approach, or if rewriting the entire function to be iterative would be better here.

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 RUST_MIN_STACK to 3MB, so N can stay relatively small and the test doesn't take forever to complete.

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 3, 2026
@oli-obk

oli-obk commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

both the current nightly and this stage1 crash during name resolution.

🤣

@oli-obk

oli-obk commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

or if rewriting the entire function to be iterative would be better here.

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

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jul 6, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Jul 6, 2026
Avoid infinite recursion when trying to build valtrees for self-referential consts
@rust-bors

rust-bors Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 5da228f (5da228f755a19e6d66549a30a446be06f9b99bb1)
Base parent: 3c00c96 (3c00c96d3af4d5b5e101e56cc161a608b21366ee)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (5da228f): comparison URL.

Overall result: no relevant changes - no action needed

Benchmarking 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 count

This 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.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.2% [1.7%, 2.5%] 3
Improvements ✅
(primary)
-0.6% [-0.6%, -0.6%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -0.6% [-0.6%, -0.6%] 1

Cycles

Results (primary -2.5%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-2.5% [-2.5%, -2.5%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -2.5% [-2.5%, -2.5%] 1

Binary size

Results (secondary 0.0%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.0% [0.0%, 0.0%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Bootstrap: 491.018s -> 494.091s (0.63%)
Artifact size: 388.45 MiB -> 388.99 MiB (0.14%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jul 6, 2026
@oli-obk

oli-obk commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

@bors r+ rollup

@rust-bors

rust-bors Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

📌 Commit c61c52f has been approved by oli-obk

It is now in the queue for this repository.

🌲 The tree is currently closed for pull requests below priority 6. This pull request will be tested once the tree is reopened.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 6, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 6, 2026
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
rust-bors Bot pushed a commit that referenced this pull request Jul 7, 2026
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)
@rust-bors rust-bors Bot merged commit ce811cd into rust-lang:main Jul 7, 2026
14 checks passed
@rustbot rustbot added this to the 1.99.0 milestone Jul 7, 2026
rust-timer added a commit that referenced this pull request Jul 7, 2026
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Using a reference to a self-referential static as a pattern causes stack overflow

6 participants