2022-05-17 16:18:40 +02:00
|
|
|
// build-fail
|
|
|
|
// compile-flags: -Copt-level=0
|
2020-09-16 03:45:58 +01:00
|
|
|
// normalize-stderr-test: ".nll/" -> "/"
|
mir: adjust conditional in recursion limit check
This commit 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 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>
2020-05-24 16:03:11 +01:00
|
|
|
|
|
|
|
fn main() {
|
|
|
|
rec(Empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Empty;
|
|
|
|
|
|
|
|
impl Iterator for Empty {
|
|
|
|
type Item = ();
|
|
|
|
fn next<'a>(&'a mut self) -> core::option::Option<()> {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn identity<T>(x: T) -> T {
|
|
|
|
x
|
|
|
|
}
|
|
|
|
|
|
|
|
fn rec<T>(mut it: T)
|
|
|
|
where
|
|
|
|
T: Iterator,
|
|
|
|
{
|
|
|
|
if () == () {
|
|
|
|
T::count(it);
|
|
|
|
} else {
|
|
|
|
rec(identity(&mut it))
|
2022-05-17 16:18:40 +02:00
|
|
|
//~^ ERROR reached the recursion limit while instantiating
|
mir: adjust conditional in recursion limit check
This commit 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 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>
2020-05-24 16:03:11 +01:00
|
|
|
}
|
|
|
|
}
|