Repository navigation
Avoid computing layout of enums with non-int discriminants - #157562
Conversation
|
This PR changes a file inside |
|
r? @Kivooeo rustbot has assigned @Kivooeo. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
I don't expect the loop to impact perf significantly, since later on in the same function we construct an iterator by calling |
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Avoid computing layout of enums with non-int discriminants
This comment has been minimized.
This comment has been minimized.
183e882 to
0ba35a5
Compare
This comment was marked as resolved.
This comment was marked as resolved.
0ba35a5 to
88d314a
Compare
|
Thanks for pointing that out, the previous version caused a cycle error, so now we just check the cached typeck results to see if those have errors instead of trying to const-eval the discriminant. |
This comment has been minimized.
This comment has been minimized.
|
This PR is still technically a breaking change, since now the following code fails to compile: pub trait Trait {
type Assoc;
}
impl Trait for [u8; 0] {
type Assoc = isize;
}
pub enum Foo {
One = unsafe { std::mem::zeroed::<<[u8; size_of::<Foo>()] as Trait>::Assoc>() },
}Error with this PR |
|
Might be an acceptable breaking change? Not sure. Would require a crater run if we go ahead with this. |
|
Finished benchmarking commit (023d36e): 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)This perf run didn't have relevant results for this metric. CyclesResults (primary -2.2%, secondary -3.3%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 514.705s -> 515.476s (0.15%) |
|
Thanks, it turns out that this simpler version causes the same error with this PR for the same reason: use std::mem::size_of;
pub enum Foo {
One = size_of::<[u8; size_of::<Foo>()]>() as isize,
}When type-checking I looked into why this doesn't cause the same query cycles on stable/nightly, and it turns out this code, with 2 variants instead of 1, doesn't compile on both current stable and nightly: use std::mem::size_of;
pub trait Trait {
type Assoc;
}
impl Trait for [u8; 0] {
type Assoc = isize;
}
pub enum Foo {
One = unsafe { std::mem::zeroed::<<[u8; size_of::<Foo>()] as Trait>::Assoc>() },
Two,
}stable playground link It seems like the reason why this happens for 2+ variants but not 1 is because the I do definitely think a crater run is still warranted. |
|
Preparing for crater run. @bors try |
This comment has been minimized.
This comment has been minimized.
Avoid computing layout of enums with non-int discriminants
|
💥 Test timed out after |
|
🔔 This is now entering its final comment period, as per the review above. 🔔 |
So I agree that queries are not part of the spec. I do think that "what requires what" at some level should be part of the spec, in so far as it accepts what programs are accepted. |
|
@rfcbot reviewed |
|
The way I see the FCP is that we are approving a change to the language spec, even though that section is currently imaginary (the language is underspecified by the reference). I think the simplest model is one where lang, or one of its delegated subteams, approve those changes. This is consistent with how the types team operates, because they have a dual lang/compiler role. On the lang side, they manage a jagged subset of the design space where the only specification we have is the implementation. In creating the team, lang delegated to their best judgment how to adapt that implementation toward a smoother language over time, one we can better reason about and specify in the long run. I expect that as that continues, they will naturally start to own parts of the reference text. |
I wouldn't expect to happen too often. New query edges which may cycle mean there's a cyclic dependency going on, which is valuable to look into as e.g. the fact that there's cyclic reasoning between trait solving and It does feel more T-types than T-lang to me. Or well, more accurately, it's enough of an implementation detail that I feel kinda iffy about having T-lang be responsible here and would like it to be delegated to a subteam. Due to a lack of better choices, I guess that subteam is T-types here 🤣 |
|
When I change code in const-eval I am usually not aware if whatever I call adds a new query edge, let alone if that can cause cycles. |
|
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. |
|
@Kivooeo when you have the time, could you take a look at this PR again? I think it should be ready to merge, though I'm not sure. sorry for the ping, and thanks! :D |
|
@bors r+ rollup |
…out, r=Kivooeo Avoid computing layout of enums with non-int discriminants Currently, enums with explicit non-int discriminants, such as `1..=10`, correctly error with E0308 and E0732 during typeck. However, `layout_of` never sees this error, since `AdtDef::discriminants()` falls back to a default value when `eval_explicit_discr` returns an `Err`, causing the layout of the enum to be broken. If this enum then appears in a promoted, we expect CTFE to fail; however, since `layout_of` technically "succeeded," just with a broken layout, our enum isn't in `allowed_in_infallible`, so CTFE expects it to succeed. CTFE failing then causes us to ICE with `"interpret const eval failure of...which is not in required_consts"`. This PR modifies `layout_of_uncached` in `compiler/rustc_ty_utils/src/layout.rs` to typeck all explicit enum discriminants before computing layout, and early-returns with a `LayoutError::ReferncesError` if eval fails. CTFE then sees this `LayoutError` as `allowed_in_infallible`, avoiding the ICE. fixes rust-lang#138660
Rollup of 9 pull requests Successful merges: - #162228 (tests: Run more pauth tests in CI and make them pass) - #162493 (Add support for -Zsanitizer-cfi-minimal-runtime) - #163271 (add a leak check test) - #163282 (cleanup: clean up more dependencies that are unused) - #157562 (Avoid computing layout of enums with non-int discriminants) - #162275 (Do not increase recursion depth for coroutine witness and rigid opaques when proving auto traits) - #163037 (fix and test `va_arg` on `f128` on `x86`) - #163114 (Add regression test for hang on mutually recursive trait impls) - #163255 (Check the entire library and cg_clif workspaces for permitted deps in tidy)
Rollup of 8 pull requests Successful merges: - #162228 (tests: Run more pauth tests in CI and make them pass) - #163271 (add a leak check test) - #163282 (cleanup: clean up more dependencies that are unused) - #157562 (Avoid computing layout of enums with non-int discriminants) - #162275 (Do not increase recursion depth for coroutine witness and rigid opaques when proving auto traits) - #163037 (fix and test `va_arg` on `f128` on `x86`) - #163114 (Add regression test for hang on mutually recursive trait impls) - #163255 (Check the entire library and cg_clif workspaces for permitted deps in tidy)
Rollup merge of #157562 - sjwang05:fix-138660-enum-discr-layout, r=Kivooeo Avoid computing layout of enums with non-int discriminants Currently, enums with explicit non-int discriminants, such as `1..=10`, correctly error with E0308 and E0732 during typeck. However, `layout_of` never sees this error, since `AdtDef::discriminants()` falls back to a default value when `eval_explicit_discr` returns an `Err`, causing the layout of the enum to be broken. If this enum then appears in a promoted, we expect CTFE to fail; however, since `layout_of` technically "succeeded," just with a broken layout, our enum isn't in `allowed_in_infallible`, so CTFE expects it to succeed. CTFE failing then causes us to ICE with `"interpret const eval failure of...which is not in required_consts"`. This PR modifies `layout_of_uncached` in `compiler/rustc_ty_utils/src/layout.rs` to typeck all explicit enum discriminants before computing layout, and early-returns with a `LayoutError::ReferncesError` if eval fails. CTFE then sees this `LayoutError` as `allowed_in_infallible`, avoiding the ICE. fixes #138660
View all comments
Currently, enums with explicit non-int discriminants, such as
1..=10, correctly error with E0308 and E0732 during typeck. However,layout_ofnever sees this error, sinceAdtDef::discriminants()falls back to a default value wheneval_explicit_discrreturns anErr, causing the layout of the enum to be broken. If this enum then appears in a promoted, we expect CTFE to fail; however, sincelayout_oftechnically "succeeded," just with a broken layout, our enum isn't inallowed_in_infallible, so CTFE expects it to succeed. CTFE failing then causes us to ICE with"interpret const eval failure of...which is not in required_consts".This PR modifies
layout_of_uncachedincompiler/rustc_ty_utils/src/layout.rsto typeck all explicit enum discriminants before computing layout, and early-returns with aLayoutError::ReferncesErrorif eval fails. CTFE then sees thisLayoutErrorasallowed_in_infallible, avoiding the ICE.fixes #138660