-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Remove redundant information in rustc_abi::Variants
#151742
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
base: main
Are you sure you want to change the base?
Changes from all commits
d1d2efd
dcc9f81
82a3a13
8f0df41
db81f4e
7c77389
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1894,7 +1894,7 @@ pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> { | |
| tag: Scalar, | ||
| tag_encoding: TagEncoding<VariantIdx>, | ||
| tag_field: FieldIdx, | ||
| variants: IndexVec<VariantIdx, LayoutData<FieldIdx, VariantIdx>>, | ||
| variants: IndexVec<VariantIdx, VariantLayout<FieldIdx>>, | ||
| }, | ||
| } | ||
|
|
||
|
|
@@ -2250,3 +2250,38 @@ pub enum AbiFromStrErr { | |
| /// no "-unwind" variant can be used here | ||
| NoExplicitUnwind, | ||
| } | ||
|
|
||
| // NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage. | ||
| #[derive(PartialEq, Eq, Hash, Clone, Debug)] | ||
| #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] | ||
| pub struct VariantLayout<FieldIdx: Idx> { | ||
| pub size: Size, | ||
| pub backend_repr: BackendRepr, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know enough about codegen to confidently say if it requires accurate reprs for enum variants, so I've left this field for now. |
||
| pub field_offsets: IndexVec<FieldIdx, Size>, | ||
| fields_in_memory_order: IndexVec<u32, FieldIdx>, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: this field could be removed and recomputed from the field offsets in |
||
| uninhabited: bool, | ||
| } | ||
|
|
||
| impl<FieldIdx: Idx> VariantLayout<FieldIdx> { | ||
| pub fn from_layout(layout: LayoutData<FieldIdx, impl Idx>) -> Self { | ||
| let FieldsShape::Arbitrary { offsets, in_memory_order } = layout.fields else { | ||
| panic!("Layout of fields should be Arbitrary for variants"); | ||
| }; | ||
|
|
||
| Self { | ||
| size: layout.size, | ||
| backend_repr: layout.backend_repr, | ||
| field_offsets: offsets, | ||
| fields_in_memory_order: in_memory_order, | ||
| uninhabited: layout.uninhabited, | ||
| } | ||
| } | ||
|
|
||
| pub fn is_uninhabited(&self) -> bool { | ||
| self.uninhabited | ||
| } | ||
|
|
||
| pub fn has_fields(&self) -> bool { | ||
| self.field_offsets.len() > 0 | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| use std::borrow::Cow; | ||
|
|
||
| use rustc_abi::{FieldIdx, TagEncoding, VariantIdx, Variants}; | ||
| use rustc_abi::{FieldIdx, TagEncoding, VariantIdx, Variants, WrappingRange}; | ||
| use rustc_codegen_ssa::debuginfo::type_names::{compute_debuginfo_type_name, cpp_like_debuginfo}; | ||
| use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo}; | ||
| use rustc_codegen_ssa::traits::MiscCodegenMethods; | ||
|
|
@@ -399,16 +399,36 @@ fn compute_discriminant_value<'ll, 'tcx>( | |
| ), | ||
| &Variants::Multiple { | ||
| tag_encoding: TagEncoding::Niche { ref niche_variants, niche_start, untagged_variant }, | ||
| tag_field, | ||
| tag, | ||
| .. | ||
| } => { | ||
| if variant_index == untagged_variant { | ||
| let valid_range = enum_type_and_layout | ||
| .for_variant(cx, variant_index) | ||
| .largest_niche | ||
| .as_ref() | ||
| .unwrap() | ||
| .valid_range; | ||
| let niche_end = niche_start | ||
| .wrapping_sub(niche_variants.start().as_u32() as u128) | ||
| .wrapping_add(niche_variants.end().as_u32() as u128); | ||
|
|
||
| // Remove discriminant values of the other variants from the largest niche. This assumes | ||
| // that the largest niche, when it exists, always corresponds to the enum discriminant. | ||
|
Comment on lines
+411
to
+412
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This assumption was already implicitly made by the original code. |
||
| let mut valid_range = WrappingRange { | ||
| start: niche_end.wrapping_add(1), | ||
| end: niche_start.wrapping_sub(1), | ||
| }; | ||
| if let Some(niche) = &enum_type_and_layout.largest_niche { | ||
| assert_eq!(enum_type_and_layout.fields.offset(tag_field.into()), niche.offset); | ||
|
|
||
| if niche.valid_range.start == niche_start { | ||
| valid_range.end = niche.valid_range.end; | ||
| } else if niche.valid_range.end == niche_end { | ||
| valid_range.start = niche.valid_range.start; | ||
| } else { | ||
| bug!( | ||
| "largest niche (range: {:?}) doesn't match with niched tag encoding (range: {:?})", | ||
| niche.valid_range, | ||
| &WrappingRange { start: niche_start, end: niche_end }, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| let min = valid_range.start.min(valid_range.end); | ||
| let min = tag.size(cx).truncate(min); | ||
|
|
||
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.
Can't be removed, as it is used by the
variant_size_differenceslint.