-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Variants::Single: do not use invalid VariantIdx for uninhabited enums #133702
Conversation
Some changes occurred in compiler/rustc_codegen_gcc This PR changes Stable MIR cc @oli-obk, @celinval, @ouz-a Some changes occurred to the CTFE / Miri interpreter cc @rust-lang/miri Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt Some changes occurred to the CTFE / Miri interpreter cc @rust-lang/miri, @rust-lang/wg-const-eval Some changes occurred to the CTFE machinery cc @rust-lang/wg-const-eval The Miri subtree was changed cc @rust-lang/miri Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 |
@@ -565,31 +564,15 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { | |||
StatementKind::SetDiscriminant { box place, variant_index } => { | |||
let Some(discr_target) = self.map.find_discr(place.as_ref()) else { return }; | |||
let enum_ty = place.ty(self.body, self.tcx).ty; | |||
// `SetDiscriminant` may be a no-op if the assigned variant is the untagged variant | |||
// of a niche encoding. If we cannot ensure that we write to the discriminant, do | |||
// nothing. |
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.
@cjgillot the old logic here seems unnecessarily cautious. Miri already for a while now considers it UB to "write" an untagged discriminant if the data does not currently encode that variant. So IMO we can also rely on this for optimizations, this slightly strengthening jump threading. (I thought we already rely on this for optimizations somewhere, but I am not sure.)
compiler/stable_mir/src/abi.rs
Outdated
@@ -181,6 +181,7 @@ impl FieldsShape { | |||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] | |||
pub enum VariantsShape { | |||
/// Single enum variants, structs/tuples, unions, and all non-ADTs. | |||
// FIXME: needs to become `Option` like in the internal type. |
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.
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.
I ended up making this a separate variant, and hence also added that variant in stable-mir.
Would introducing |
I considered that, but I think that would make for a larger diff overall. Also, unless we want to enforce that all uninhabited types use But maybe I should actually give it a try to see how it pans out. |
This comment has been minimized.
This comment has been minimized.
1114912
to
c7b2a22
Compare
This comment has been minimized.
This comment has been minimized.
c7b2a22
to
1b86d85
Compare
rust-analyzer is developed in its own repository. If possible, consider making this change to rust-lang/rust-analyzer instead. cc @rust-lang/rust-analyzer |
This comment has been minimized.
This comment has been minimized.
1b86d85
to
7a7e0db
Compare
This comment has been minimized.
This comment has been minimized.
a610961
to
fa08c41
Compare
Yeah that works pretty well. :) |
if index == variant_index && | ||
// Don't confuse variants of uninhabited enums with the enum itself. | ||
// For more details see https://github.com/rust-lang/rust/issues/69763. | ||
this.fields != FieldsShape::Primitive => |
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.
Now that !
and hence empty enums use Variants::Empty
, this check does not seem to be needed any more. :)
fa08c41
to
e0bab7d
Compare
@@ -1638,6 +1638,7 @@ impl Evaluator<'_> { | |||
return Ok(0); | |||
}; | |||
match &layout.variants { | |||
Variants::Empty => unreachable!(), |
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.
I don't know why this is unreachable, but the old logic would already have panicked here in at least some of same cases since the variants[index.0]
below would fail for no-variant enums.
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.
It seems to be used only in mir evaluator, which I guess would not go into unreachable code.
b90ebfb
to
786730a
Compare
c55262f
to
316c70f
Compare
The PR this is based on landed, so this is ready for review. :) |
compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
Outdated
Show resolved
Hide resolved
// Types without variants use `0` as dummy variant index. | ||
assert!(index.as_u32() == 0); |
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.
Isn't the point of this PR to get rid of this hack?
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.
No. There are actually two hacks:
- Some types don't have a concept of "variant", like tuples or primitives. Those are still
Variants::Single
and that makes sense, and they use index 0. I considered making this anOption
but then the value 0 has to be duplicated in all codegen backends, so centralizing that in the layout logic seems better. - Some types are actually 0-variant types. Those are being changed in this PR.
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.
The key invariant this PR achieves is that if we have Variants::Single
, and if the type has a discriminant_range
, then the index is in that range. This is useful because it means if the type is an ADT, we can use the single variant index to index the variant list without ICEing. So far, this always requires a special check for empty enums, which is error-prone.
Rollup of 8 pull requests Successful merges: - rust-lang#133702 (Variants::Single: do not use invalid VariantIdx for uninhabited enums) - rust-lang#133926 (Fix const conditions for RPITITs) - rust-lang#134161 (Overhaul token cursors) - rust-lang#134253 (Overhaul keyword handling) - rust-lang#134394 (Clarify the match ergonomics 2024 migration lint's output) - rust-lang#134420 (refactor: replace &PathBuf with &Path to enhance generality) - rust-lang#134444 (Fix `x build --stage 1 std` when using cg_cranelift as the default backend) - rust-lang#134452 (fix(LazyCell): documentation of get[_mut] was wrong) r? `@ghost` `@rustbot` modify labels: rollup
Trying to see: |
Variants::Single: do not use invalid VariantIdx for uninhabited enums ~~Stacked on top of rust-lang#133681, only the last commit is new.~~ Currently, `Variants::Single` for an empty enum contains a `VariantIdx` of 0; looking that up in the enum variant list will ICE. That's quite confusing. So let's fix that by adding a new `Variants::Empty` case for types that have 0 variants. try-job: i686-msvc
Oh gosh, do we have a windows person that knows this debug info stuff? If I can't even run the tests, how am I supposed to fix them?^^ It seems odd though since the enums mentioned there all do have inhabited variants, so nothing should change about them... |
I can try to run this locally in a moment. |
Ok so I ran this locally, and it doesn't fail with cdb distributed as part of
I wonder if cdb just somehow failed to init properly... Probably requeue this PR once the try job comes back, no idea what actually went wrong... I only had a vague suspicion for this PR as this PR seemed to be the only one that actually touched debuginfo remotely 🤷 |
☀️ Try build successful - checks-actions |
I know those test quite well so I can look into it tomorrow morning if you have not it figured by then.
There were some breaking changes in WinDbg, so that might be a factor.
…On Wed, 18 Dec 2024, at 15:01, Ralf Jung wrote:
Oh gosh, do we have a windows person that knows this debug info stuff? If I can't even run the tests, how am I supposed to fix them?^^
It seems odd though since the enums mentioned there all do have inhabited variants, so nothing should change about them...
—
Reply to this email directly, view it on GitHub <#133702 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/BNUYRJZTRRALYFHIPG7KUN32GF54JAVCNFSM6AAAAABSZVHGZOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNJRGQYDAMZYHA>.
You are receiving this because you commented.Message ID: ***@***.***>
|
There is a breaking change in 26100. I have fixes for that locally. (Looking just from phone so I am guessing that is the problem.)
On Wed, 18 Dec 2024, at 15:51, 许杰友 Jieyou Xu (Joe) wrote:
Ok so I ran this locally, and it doesn't fail with cdb distributed as part of `10.0.26100.1742`. I stared at the rollup log at it had stuff like
`tests\debuginfo\issue-13213.rs ... ignored, ignored when the debugger is cdb (Fails with exit code 0xc0000135 ("the application failed to initialize properly"))
`
… I wonder if cdb just somehow failed to init properly... Probably requeue this PR once the try job comes back, no idea what actually went wrong...
—
Reply to this email directly, view it on GitHub <#133702 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/BNUYRJ4HR3IDVSHH64F6R3L2GGDWLAVCNFSM6AAAAABSZVHGZOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNJRGUYTMOBTG4>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Would be great if you could double-check the test if this PR fails again, at the moment I can't repro the failure, so it might be spurious somehow in the rollup... |
Rollup of 7 pull requests Successful merges: - rust-lang#133702 (Variants::Single: do not use invalid VariantIdx for uninhabited enums) - rust-lang#134427 (ci: remove duplicate task definition) - rust-lang#134432 (Fix intra doc links not generated inside footnote definitions) - rust-lang#134437 (reduce compiler `Assemble` complexity) - rust-lang#134474 (Forbid overwriting types in typeck) - rust-lang#134477 (move lint_unused_mut into sub-fn) - rust-lang#134491 (Some destructor/drop related tweaks) r? `@ghost` `@rustbot` modify labels: rollup
Everything is green for me. |
Rollup merge of rust-lang#133702 - RalfJung:single-variant, r=oli-obk Variants::Single: do not use invalid VariantIdx for uninhabited enums ~~Stacked on top of rust-lang#133681, only the last commit is new.~~ Currently, `Variants::Single` for an empty enum contains a `VariantIdx` of 0; looking that up in the enum variant list will ICE. That's quite confusing. So let's fix that by adding a new `Variants::Empty` case for types that have 0 variants. try-job: i686-msvc
Variants::Single: do not use invalid VariantIdx for uninhabited enums ~~Stacked on top of rust-lang#133681, only the last commit is new.~~ Currently, `Variants::Single` for an empty enum contains a `VariantIdx` of 0; looking that up in the enum variant list will ICE. That's quite confusing. So let's fix that by adding a new `Variants::Empty` case for types that have 0 variants. try-job: i686-msvc
Propagated from rust-lang/rust#133702. Empty enums now have `Variants::Empty` as variants instead of `Variants::Single{ index: None }`.
Propagated from rust-lang/rust#133702. Empty enums now have `Variants::Empty` as variants instead of `Variants::Single{ index: None }`.
Propagated from rust-lang/rust#133702. Empty enums now have `Variants::Empty` as variants instead of `Variants::Single{ index: None }`.
Stacked on top of #133681, only the last commit is new.Currently,
Variants::Single
for an empty enum contains aVariantIdx
of 0; looking that up in the enum variant list will ICE. That's quite confusing. So let's fix that by adding a newVariants::Empty
case for types that have 0 variants.try-job: i686-msvc