-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mir: adjust conditional in recursion limit check #72540
mir: adjust conditional in recursion limit check #72540
Conversation
r? @varkor (rust_highfive has picked a reviewer for you, use r? to override) |
6a06e4c
to
70b944b
Compare
It seems this inconsistency is found in more places throughout the compiler, e.g. in these two locations Do you think you could audit these limits and add a comment somewhere appropriate mentioning this? |
It seems reasonable to add a struct somewhere with check and increment methods that would store recursion limits and be used throughout the compiler, to hopefully prevent this from happening again. |
I've added a commit with a |
This comment has been minimized.
This comment has been minimized.
126e7b9
to
cac732b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me. r=me with the name change, or similar.
This commit adjusts the condition used in the recursion limit check of the monomorphization collector, from `>` to `>=`. In rust-lang#67552, the test case had infinite indirect recursion, repeating a handful of functions (from the perspective of the monomorphization collector): `rec` -> `identity` -> `Iterator::count` -> `Iterator::fold` -> `Iterator::next` -> `rec`. During this process, `resolve_associated_item` was invoked for `Iterator::fold` (during the construction of an `Instance`), and ICE'd due to substitutions needing inference. However, previous iterations of this recursion would have called this function for `Iterator::fold` - and did! - and succeeded in doing so (trivially checkable from debug logging, `()` is present where `_` is in the substs of the failing execution). The expected outcome of this test case would be a recursion limit error (which is present when the `identity` fn indirection is removed), and the recursion depth of `rec` is increasing (other functions finish collecting their neighbours and thus have their recursion depths reset). When the ICE occurs, the recursion depth of `rec` is 256 (which matches the recursion limit), which suggests perhaps that a different part of the compiler is using a `>=` comparison and returning a different result on this recursion rather than what it returned in every previous recursion, thus stopping the monomorphization collector from reporting an error on the next recursion, where `recursion_depth_of_rec > 256` would have been true. With grep and some educated guesses, we can determine that the recursion limit check at line 818 in `src/librustc_trait_selection/traits/project.rs` is the other check that is using a different comparison. Modifying either comparison to be `>` or `>=` respectively will fix the error, but changing the monomorphization collector produces the nicer error. Signed-off-by: David Wood <david@davidtw.co>
This commit introduces a `Limit` type which is used to ensure that all comparisons against limits within the compiler are consistent (which can result in ICEs if they aren't). Signed-off-by: David Wood <david@davidtw.co>
cac732b
to
a54ed87
Compare
@bors r=varkor |
📌 Commit a54ed87 has been approved by |
Rollup of 9 pull requests Successful merges: - rust-lang#72299 (more `LocalDefId`s) - rust-lang#72368 (Resolve overflow behavior for RangeFrom) - rust-lang#72441 (Fix ICE with explicit late-bound lifetimes) - rust-lang#72499 (Override Box::<[T]>::clone_from) - rust-lang#72521 (Properly handle InlineAsmOperand::SymFn when collecting monomorphized items) - rust-lang#72540 (mir: adjust conditional in recursion limit check) - rust-lang#72563 (multiple Return terminators are possible) - rust-lang#72585 (Only capture tokens for items with outer attributes) - rust-lang#72607 (Eagerly lower asm sub-expressions to HIR even if there is an error) Failed merges: r? @ghost
Fixes #67552.
This PR adjusts the condition used in the recursion limit check of
the monomorphization collector, from
>
to>=
.In #67552, the test case had infinite indirect recursion, repeating a
handful of functions (from the perspective of the monomorphization
collector):
rec
->identity
->Iterator::count
->Iterator::fold
->
Iterator::next
->rec
.During this process,
resolve_associated_item
was invoked forIterator::fold
(during the construction of anInstance
), andICE'd due to substitutions needing inference. However, previous
iterations of this recursion would have called this function for
Iterator::fold
- and did! - and succeeded in doing so (triviallycheckable from debug logging,
()
is present where_
is in the substsof the failing execution).
The expected outcome of this test case would be a recursion limit error
(which is present when the
identity
fn indirection is removed), andthe recursion depth of
rec
is increasing (other functions finishcollecting their neighbours and thus have their recursion depths reset).
When the ICE occurs, the recursion depth of
rec
is 256 (which matchesthe recursion limit), which suggests perhaps that a different part of
the compiler is using a
>=
comparison and returning a different resulton this recursion rather than what it returned in every previous
recursion, thus stopping the monomorphization collector from reporting
an error on the next recursion, where
recursion_depth_of_rec > 256
would have been true.
With grep and some educated guesses, we can determine that
the recursion limit check at line 818 in
src/librustc_trait_selection/traits/project.rs
is the other check thatis using a different comparison. Modifying either comparison to be
>
or>=
respectively will fix the error, but changing the monomorphizationcollector produces the nicer error.