-
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
rustc endless loop on some constant casts #67539
Comments
Here's a playground link that better illustrates the failure. It builds with |
(Never mind that the code is wrong: casting a negative number to |
Since casting negative numbers to usize seems really wrong (and it triggers rust-lang/rust#67539 on nightlies). Let's use .count_ones() to get a guarantee that the number we have is non-zero instead.
similar "endless" loop: #63952 The problem here is that you have an overflow essentially giving you cc @wesleywiser |
for arrays of zsts we can solve this, but if you used let mut x = MaybeUninit::<[T; N]>::uninit();
for i in &mut x {
*x = X;
}
let x = x.assert_initialized(); |
I thought this might have been fixed by #66394, but because it's a ZST, it doesn't trigger that logic. It would probably be easy to extend that logic to include large arrays of ZSTs. |
While we could fix this just for const prop, we'd still have the same problem in const eval, so we should consider a general solution. |
That would solve tons of problems I think. Having a single MIR statement turn into a loop in the interpreter is pretty suboptimal anyway -- usually every statement should have a fixed upper bound on its execution time. As an interim solution we could probably skip this part for arrays of ZST. |
Or probably it makes more sense to skip this loop if the size is 0. |
Or we just make the first line of rust/src/librustc_mir/interpret/memory.rs Lines 825 to 832 in a916ac2
if size == Size::ZERO || length == 0 { return Ok(()) }
That way we can even remove rust/src/librustc_mir/interpret/step.rs Line 208 in a916ac2
|
No, we have to still check those pointers to not be dangling. |
I thought writes of zsts to dangling pointers is fine? Though yea, I'm unsure about writing zero elements of non-zsts to a destination. |
Oh wait, looks like we expect the caller to check that. Hm. I'd probably bail out after getting |
Not always, no. If the pointer is a |
Ok, so to any implementor: basically bail out from just before rust/src/librustc_mir/interpret/memory.rs Line 849 in a916ac2
dest_bytes.is_empty() and leave a comment explaining that this is an optimization to not run anything for zsts. You can reference this issue, too.
|
It looks to me like the compiler is busy validating every ty::Tuple(t) if t.len() == 0 => true to this match rust/src/librustc_mir/interpret/validity.rs Lines 585 to 588 in a916ac2
then the compilation completes in ~0.2 seconds. I'm not sure that's a valid fix though. Do we actually need to validate every ZST in the array? |
Well, the ZST could be |
Ah, yeah that's a great point. I believe |
Well... any zst that is not uninhabited can do this early bail out, so I think checking with https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/struct.TyCtxt.html#method.is_ty_uninhabited_from_any_module for uninhabitedness and then checking the element's zst-ness would work |
I wouldn't use |
This extends the existing logic which skips validating every integer or floating point number type to also skip validating empty structs because they are also trivially valid. Fixes rust-lang#67539
…d_constants, r=oli-obk Resolve long compile times when evaluating always valid constants This extends the existing logic which skips validating every integer or floating point number type to also skip validating empty structs because they are also trivially valid. Fixes rust-lang#67539 r? @oli-obk cc @RalfJung @spastorino
This extends the existing logic which skips validating every integer or floating point number type to also skip validating empty structs because they are also trivially valid. Fixes rust-lang#67539
…, r=oli-obk Resolve long compile times when evaluating always valid constants This extends the existing logic which skips validating every integer or floating point number type to also skip validating empty structs because they are also trivially valid. Fixes #67539 r? @oli-obk cc @RalfJung @spastorino
Huh, so. From the behavior I reported in bheisler/criterion.rs#377, it looks like the buggy change made it to 1.41.0 stable, but the fix didn't? My crate's benchmark compilation is currently hanging with what looks like these exact symptoms. |
This extends the existing logic which skips validating every integer or floating point number type to also skip validating empty structs because they are also trivially valid. Fixes rust-lang#67539
I bisected nightlies to figure out when my pull request's tests started breaking on nightly. The following is the template
cargo-bisect-rustc
gave me.Regression found in the compiler
searched nightlies: from nightly-2019-10-01 to nightly-2019-12-22
regressed nightly: nightly-2019-11-20
searched commits: from 3e525e3 to 618b01f
regressed commit: d1da802
source code: antifuchs/nonzero_ext#7
Instructions
I tried the following on macOS and linux (in CI):
cargo +nightly test --test=compiletest
with a nightly version later than d1da802, that is >=nightly-2019-11-20
Error
The compile test (provided by trybuild) does not terminate - rustc seems to be running forever, consuming 99% of my CPU all the while.
Since the instructions to repro are a bit convoluted (and massive), I'll try and boil down the repro case a little bit.
The text was updated successfully, but these errors were encountered: