From f7d745f33d950c050e0a5a2ee2ee9f0e1269e956 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 23 May 2020 13:22:45 +0200 Subject: [PATCH] tag/niche terminology cleanup --- .../debuginfo/metadata.rs | 105 +++++++++--------- src/librustc_codegen_ssa/mir/place.rs | 44 ++++---- src/librustc_lint/types.rs | 14 +-- src/librustc_middle/ty/layout.rs | 58 +++++----- src/librustc_mir/interpret/operand.rs | 27 ++--- src/librustc_mir/interpret/place.rs | 41 +++---- src/librustc_mir/interpret/step.rs | 4 +- src/librustc_mir/interpret/validity.rs | 4 +- src/librustc_target/abi/mod.rs | 27 +++-- src/test/ui/layout/debug.stderr | 12 +- 10 files changed, 167 insertions(+), 169 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 0cce0b25e589..01f630a31a18 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1,4 +1,4 @@ -use self::EnumDiscriminantInfo::*; +use self::EnumTagInfo::*; use self::MemberDescriptionFactory::*; use self::RecursiveTypeDescription::*; @@ -40,7 +40,7 @@ use rustc_middle::{bug, span_bug}; use rustc_session::config::{self, DebugInfo}; use rustc_span::symbol::{Interner, Symbol}; use rustc_span::{self, SourceFile, SourceFileHash, Span}; -use rustc_target::abi::{Abi, Align, DiscriminantKind, HasDataLayout, Integer, LayoutOf}; +use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, LayoutOf, TagEncoding}; use rustc_target::abi::{Int, Pointer, F32, F64}; use rustc_target::abi::{Primitive, Size, VariantIdx, Variants}; @@ -1335,7 +1335,7 @@ fn generator_layout_and_saved_local_names( struct EnumMemberDescriptionFactory<'ll, 'tcx> { enum_type: Ty<'tcx>, layout: TyAndLayout<'tcx>, - discriminant_type_metadata: Option<&'ll DIType>, + tag_type_metadata: Option<&'ll DIType>, containing_scope: &'ll DIScope, span: Span, } @@ -1385,7 +1385,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, self.layout, variant_info, - NoDiscriminant, + NoTag, self_metadata, self.span, ); @@ -1409,19 +1409,19 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { }] } Variants::Multiple { - discr_kind: DiscriminantKind::Tag, - discr_index, + tag_encoding: TagEncoding::Direct, + tag_field, ref variants, .. } => { - let discriminant_info = if fallback { - RegularDiscriminant { - discr_field: Field::from(discr_index), - discr_type_metadata: self.discriminant_type_metadata.unwrap(), + let tag_info = if fallback { + RegularTag { + tag_field: Field::from(tag_field), + tag_type_metadata: self.tag_type_metadata.unwrap(), } } else { // This doesn't matter in this case. - NoDiscriminant + NoTag }; variants .iter_enumerated() @@ -1432,7 +1432,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, variant, variant_info, - discriminant_info, + tag_info, self_metadata, self.span, ); @@ -1467,11 +1467,11 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { .collect() } Variants::Multiple { - discr_kind: - DiscriminantKind::Niche { ref niche_variants, niche_start, dataful_variant }, - ref discr, + tag_encoding: + TagEncoding::Niche { ref niche_variants, niche_start, dataful_variant }, + ref tag, ref variants, - discr_index, + tag_field, } => { if fallback { let variant = self.layout.for_variant(cx, dataful_variant); @@ -1480,7 +1480,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, variant, variant_info_for(dataful_variant), - OptimizedDiscriminant, + OptimizedTag, self.containing_scope, self.span, ); @@ -1524,8 +1524,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, &mut name, self.layout, - self.layout.fields.offset(discr_index), - self.layout.field(cx, discr_index).size, + self.layout.fields.offset(tag_field), + self.layout.field(cx, tag_field).size, ); variant_info_for(*niche_variants.start()).map_struct_name(|variant_name| { name.push_str(variant_name); @@ -1552,7 +1552,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, variant, variant_info, - OptimizedDiscriminant, + OptimizedTag, self_metadata, self.span, ); @@ -1573,7 +1573,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { let value = (i.as_u32() as u128) .wrapping_sub(niche_variants.start().as_u32() as u128) .wrapping_add(niche_start); - let value = truncate(value, discr.value.size(cx)); + let value = truncate(value, tag.value.size(cx)); // NOTE(eddyb) do *NOT* remove this assert, until // we pass the full 128-bit value to LLVM, otherwise // truncation will be silent and remain undetected. @@ -1603,7 +1603,7 @@ struct VariantMemberDescriptionFactory<'ll, 'tcx> { /// Cloned from the `layout::Struct` describing the variant. offsets: Vec, args: Vec<(String, Ty<'tcx>)>, - discriminant_type_metadata: Option<&'ll DIType>, + tag_type_metadata: Option<&'ll DIType>, span: Span, } @@ -1617,7 +1617,7 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> { MemberDescription { name: name.to_string(), type_metadata: if use_enum_fallback(cx) { - match self.discriminant_type_metadata { + match self.tag_type_metadata { // Discriminant is always the first field of our variant // when using the enum fallback. Some(metadata) if i == 0 => metadata, @@ -1638,10 +1638,10 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> { } #[derive(Copy, Clone)] -enum EnumDiscriminantInfo<'ll> { - RegularDiscriminant { discr_field: Field, discr_type_metadata: &'ll DIType }, - OptimizedDiscriminant, - NoDiscriminant, +enum EnumTagInfo<'ll> { + RegularTag { tag_field: Field, tag_type_metadata: &'ll DIType }, + OptimizedTag, + NoTag, } #[derive(Copy, Clone)] @@ -1706,7 +1706,7 @@ fn describe_enum_variant( cx: &CodegenCx<'ll, 'tcx>, layout: layout::TyAndLayout<'tcx>, variant: VariantInfo<'_, 'tcx>, - discriminant_info: EnumDiscriminantInfo<'ll>, + discriminant_info: EnumTagInfo<'ll>, containing_scope: &'ll DIScope, span: Span, ) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) { @@ -1722,12 +1722,12 @@ fn describe_enum_variant( let (offsets, args) = if use_enum_fallback(cx) { // If this is not a univariant enum, there is also the discriminant field. let (discr_offset, discr_arg) = match discriminant_info { - RegularDiscriminant { discr_field, .. } => { + RegularTag { tag_field, .. } => { // We have the layout of an enum variant, we need the layout of the outer enum let enum_layout = cx.layout_of(layout.ty); - let offset = enum_layout.fields.offset(discr_field.as_usize()); + let offset = enum_layout.fields.offset(tag_field.as_usize()); let args = - ("RUST$ENUM$DISR".to_owned(), enum_layout.field(cx, discr_field.as_usize()).ty); + ("RUST$ENUM$DISR".to_owned(), enum_layout.field(cx, tag_field.as_usize()).ty); (Some(offset), Some(args)) } _ => (None, None), @@ -1757,8 +1757,8 @@ fn describe_enum_variant( let member_description_factory = VariantMDF(VariantMemberDescriptionFactory { offsets, args, - discriminant_type_metadata: match discriminant_info { - RegularDiscriminant { discr_type_metadata, .. } => Some(discr_type_metadata), + tag_type_metadata: match discriminant_info { + RegularTag { tag_type_metadata, .. } => Some(tag_type_metadata), _ => None, }, span, @@ -1880,18 +1880,18 @@ fn prepare_enum_metadata( if let ( &Abi::Scalar(_), - &Variants::Multiple { discr_kind: DiscriminantKind::Tag, ref discr, .. }, + &Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, .. }, ) = (&layout.abi, &layout.variants) { - return FinalMetadata(discriminant_type_metadata(discr.value)); + return FinalMetadata(discriminant_type_metadata(tag.value)); } if use_enum_fallback(cx) { let discriminant_type_metadata = match layout.variants { Variants::Single { .. } - | Variants::Multiple { discr_kind: DiscriminantKind::Niche { .. }, .. } => None, - Variants::Multiple { discr_kind: DiscriminantKind::Tag, ref discr, .. } => { - Some(discriminant_type_metadata(discr.value)) + | Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => None, + Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, .. } => { + Some(discriminant_type_metadata(tag.value)) } }; @@ -1927,7 +1927,7 @@ fn prepare_enum_metadata( EnumMDF(EnumMemberDescriptionFactory { enum_type, layout, - discriminant_type_metadata, + tag_type_metadata: discriminant_type_metadata, containing_scope, span, }), @@ -1943,16 +1943,13 @@ fn prepare_enum_metadata( Variants::Single { .. } => None, Variants::Multiple { - discr_kind: DiscriminantKind::Niche { .. }, - ref discr, - discr_index, - .. + tag_encoding: TagEncoding::Niche { .. }, ref tag, tag_field, .. } => { // Find the integer type of the correct size. - let size = discr.value.size(cx); - let align = discr.value.align(cx); + let size = tag.value.size(cx); + let align = tag.value.align(cx); - let discr_type = match discr.value { + let tag_type = match tag.value { Int(t, _) => t, F32 => Integer::I32, F64 => Integer::I64, @@ -1960,7 +1957,7 @@ fn prepare_enum_metadata( } .to_ty(cx.tcx, false); - let discr_metadata = basic_type_metadata(cx, discr_type); + let tag_metadata = basic_type_metadata(cx, tag_type); unsafe { Some(llvm::LLVMRustDIBuilderCreateMemberType( DIB(cx), @@ -1971,17 +1968,15 @@ fn prepare_enum_metadata( UNKNOWN_LINE_NUMBER, size.bits(), align.abi.bits() as u32, - layout.fields.offset(discr_index).bits(), + layout.fields.offset(tag_field).bits(), DIFlags::FlagArtificial, - discr_metadata, + tag_metadata, )) } } - Variants::Multiple { - discr_kind: DiscriminantKind::Tag, ref discr, discr_index, .. - } => { - let discr_type = discr.value.to_ty(cx.tcx); + Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, tag_field, .. } => { + let discr_type = tag.value.to_ty(cx.tcx); let (size, align) = cx.size_and_align_of(discr_type); let discr_metadata = basic_type_metadata(cx, discr_type); @@ -1995,7 +1990,7 @@ fn prepare_enum_metadata( UNKNOWN_LINE_NUMBER, size.bits(), align.bits() as u32, - layout.fields.offset(discr_index).bits(), + layout.fields.offset(tag_field).bits(), DIFlags::FlagArtificial, discr_metadata, )) @@ -2081,7 +2076,7 @@ fn prepare_enum_metadata( EnumMDF(EnumMemberDescriptionFactory { enum_type, layout, - discriminant_type_metadata: None, + tag_type_metadata: None, containing_scope, span, }), diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 2be067938290..0c8638b673d4 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -10,7 +10,7 @@ use rustc_middle::mir; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout}; use rustc_middle::ty::{self, Ty}; -use rustc_target::abi::{Abi, Align, DiscriminantKind, FieldsShape, Int}; +use rustc_target::abi::{Abi, Align, FieldsShape, Int, TagEncoding}; use rustc_target::abi::{LayoutOf, VariantIdx, Variants}; #[derive(Copy, Clone, Debug)] @@ -199,7 +199,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { if self.layout.abi.is_uninhabited() { return bx.cx().const_undef(cast_to); } - let (discr_scalar, discr_kind, discr_index) = match self.layout.variants { + let (tag_scalar, tag_encoding, tag_field) = match self.layout.variants { Variants::Single { index } => { let discr_val = self .layout @@ -208,33 +208,33 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { .map_or(index.as_u32() as u128, |discr| discr.val); return bx.cx().const_uint_big(cast_to, discr_val); } - Variants::Multiple { ref discr, ref discr_kind, discr_index, .. } => { - (discr, discr_kind, discr_index) + Variants::Multiple { ref tag, ref tag_encoding, tag_field, .. } => { + (tag, tag_encoding, tag_field) } }; // Read the tag/niche-encoded discriminant from memory. - let encoded_discr = self.project_field(bx, discr_index); - let encoded_discr = bx.load_operand(encoded_discr); + let tag = self.project_field(bx, tag_field); + let tag = bx.load_operand(tag); // Decode the discriminant (specifically if it's niche-encoded). - match *discr_kind { - DiscriminantKind::Tag => { - let signed = match discr_scalar.value { + match *tag_encoding { + TagEncoding::Direct => { + let signed = match tag_scalar.value { // We use `i1` for bytes that are always `0` or `1`, // e.g., `#[repr(i8)] enum E { A, B }`, but we can't // let LLVM interpret the `i1` as signed, because // then `i1 1` (i.e., `E::B`) is effectively `i8 -1`. - Int(_, signed) => !discr_scalar.is_bool() && signed, + Int(_, signed) => !tag_scalar.is_bool() && signed, _ => false, }; - bx.intcast(encoded_discr.immediate(), cast_to, signed) + bx.intcast(tag.immediate(), cast_to, signed) } - DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start } => { + TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => { // Rebase from niche values to discriminants, and check // whether the result is in range for the niche variants. - let niche_llty = bx.cx().immediate_backend_type(encoded_discr.layout); - let encoded_discr = encoded_discr.immediate(); + let niche_llty = bx.cx().immediate_backend_type(tag.layout); + let tag = tag.immediate(); // We first compute the "relative discriminant" (wrt `niche_variants`), // that is, if `n = niche_variants.end() - niche_variants.start()`, @@ -248,9 +248,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { let relative_discr = if niche_start == 0 { // Avoid subtracting `0`, which wouldn't work for pointers. // FIXME(eddyb) check the actual primitive type here. - encoded_discr + tag } else { - bx.sub(encoded_discr, bx.cx().const_uint_big(niche_llty, niche_start)) + bx.sub(tag, bx.cx().const_uint_big(niche_llty, niche_start)) }; let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32(); let is_niche = { @@ -312,8 +312,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { Variants::Single { index } => { assert_eq!(index, variant_index); } - Variants::Multiple { discr_kind: DiscriminantKind::Tag, discr_index, .. } => { - let ptr = self.project_field(bx, discr_index); + Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } => { + let ptr = self.project_field(bx, tag_field); let to = self.layout.ty.discriminant_for_variant(bx.tcx(), variant_index).unwrap().val; bx.store( @@ -323,9 +323,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { ); } Variants::Multiple { - discr_kind: - DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start }, - discr_index, + tag_encoding: + TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start }, + tag_field, .. } => { if variant_index != dataful_variant { @@ -339,7 +339,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bx.memset(self.llval, fill_byte, size, self.align, MemFlags::empty()); } - let niche = self.project_field(bx, discr_index); + let niche = self.project_field(bx, tag_field); let niche_llty = bx.cx().immediate_backend_type(niche.layout); let niche_value = variant_index.as_u32() - niche_variants.start().as_u32(); let niche_value = (niche_value as u128).wrapping_add(niche_start); diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 703c2a7a443a..6f4e2c69e339 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -16,7 +16,7 @@ use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; use rustc_span::source_map; use rustc_span::symbol::sym; use rustc_span::Span; -use rustc_target::abi::{DiscriminantKind, Integer, LayoutOf, VariantIdx, Variants}; +use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants}; use rustc_target::spec::abi::Abi; use log::debug; @@ -1036,15 +1036,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { }; let (variants, tag) = match layout.variants { Variants::Multiple { - discr_kind: DiscriminantKind::Tag, - ref discr, + tag_encoding: TagEncoding::Direct, + ref tag, ref variants, .. - } => (variants, discr), + } => (variants, tag), _ => return, }; - let discr_size = tag.value.size(&cx.tcx).bytes(); + let tag_size = tag.value.size(&cx.tcx).bytes(); debug!( "enum `{}` is {} bytes large with layout:\n{:#?}", @@ -1058,8 +1058,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { .iter() .zip(variants) .map(|(variant, variant_layout)| { - // Subtract the size of the enum discriminant. - let bytes = variant_layout.size.bytes().saturating_sub(discr_size); + // Subtract the size of the enum tag. + let bytes = variant_layout.size.bytes().saturating_sub(tag_size); debug!("- variant `{}` is {} bytes large", variant.ident, bytes); bytes diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs index 5566e187c0c5..fde2627e29dc 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/src/librustc_middle/ty/layout.rs @@ -975,13 +975,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { return Ok(tcx.intern_layout(Layout { variants: Variants::Multiple { - discr: niche_scalar, - discr_kind: DiscriminantKind::Niche { + tag: niche_scalar, + tag_encoding: TagEncoding::Niche { dataful_variant: i, niche_variants, niche_start, }, - discr_index: 0, + tag_field: 0, variants: st, }, fields: FieldsShape::Arbitrary { @@ -1217,9 +1217,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { tcx.intern_layout(Layout { variants: Variants::Multiple { - discr: tag, - discr_kind: DiscriminantKind::Tag, - discr_index: 0, + tag, + tag_encoding: TagEncoding::Direct, + tag_field: 0, variants: layout_variants, }, fields: FieldsShape::Arbitrary { @@ -1400,15 +1400,15 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // Build a prefix layout, including "promoting" all ineligible // locals as part of the prefix. We compute the layout of all of // these fields at once to get optimal packing. - let discr_index = substs.as_generator().prefix_tys().count(); + let tag_index = substs.as_generator().prefix_tys().count(); // `info.variant_fields` already accounts for the reserved variants, so no need to add them. let max_discr = (info.variant_fields.len() - 1) as u128; let discr_int = Integer::fit_unsigned(max_discr); let discr_int_ty = discr_int.to_ty(tcx, false); - let discr = Scalar { value: Primitive::Int(discr_int, false), valid_range: 0..=max_discr }; - let discr_layout = self.tcx.intern_layout(Layout::scalar(self, discr.clone())); - let discr_layout = TyAndLayout { ty: discr_int_ty, layout: discr_layout }; + let tag = Scalar { value: Primitive::Int(discr_int, false), valid_range: 0..=max_discr }; + let tag_layout = self.tcx.intern_layout(Layout::scalar(self, tag.clone())); + let tag_layout = TyAndLayout { ty: discr_int_ty, layout: tag_layout }; let promoted_layouts = ineligible_locals .iter() @@ -1419,7 +1419,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { .as_generator() .prefix_tys() .map(|ty| self.layout_of(ty)) - .chain(iter::once(Ok(discr_layout))) + .chain(iter::once(Ok(tag_layout))) .chain(promoted_layouts) .collect::, _>>()?; let prefix = self.univariant_uninterned( @@ -1442,7 +1442,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // "a" (`0..b_start`) and "b" (`b_start..`) correspond to // "outer" and "promoted" fields respectively. - let b_start = (discr_index + 1) as u32; + let b_start = (tag_index + 1) as u32; let offsets_b = offsets.split_off(b_start as usize); let offsets_a = offsets; @@ -1559,9 +1559,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let layout = tcx.intern_layout(Layout { variants: Variants::Multiple { - discr, - discr_kind: DiscriminantKind::Tag, - discr_index, + tag: tag, + tag_encoding: TagEncoding::Direct, + tag_field: tag_index, variants, }, fields: outer_fields, @@ -1681,7 +1681,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } } - Variants::Multiple { ref discr, ref discr_kind, .. } => { + Variants::Multiple { ref tag, ref tag_encoding, .. } => { debug!( "print-type-size `{:#?}` adt general variants def {}", layout.ty, @@ -1703,8 +1703,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { record( adt_kind.into(), adt_packed, - match discr_kind { - DiscriminantKind::Tag => Some(discr.value.size(self)), + match tag_encoding { + TagEncoding::Direct => Some(tag.value.size(self)), _ => None, }, variant_infos, @@ -2029,11 +2029,11 @@ where fn field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> C::TyAndLayout { let tcx = cx.tcx(); - let discr_layout = |discr: &Scalar| -> C::TyAndLayout { - let layout = Layout::scalar(cx, discr.clone()); + let tag_layout = |tag: &Scalar| -> C::TyAndLayout { + let layout = Layout::scalar(cx, tag.clone()); MaybeResult::from(Ok(TyAndLayout { layout: tcx.intern_layout(layout), - ty: discr.value.to_ty(tcx), + ty: tag.value.to_ty(tcx), })) }; @@ -2110,9 +2110,9 @@ where .unwrap() .nth(i) .unwrap(), - Variants::Multiple { ref discr, discr_index, .. } => { - if i == discr_index { - return discr_layout(discr); + Variants::Multiple { ref tag, tag_field, .. } => { + if i == tag_field { + return tag_layout(tag); } substs.as_generator().prefix_tys().nth(i).unwrap() } @@ -2129,9 +2129,9 @@ where Variants::Single { index } => def.variants[index].fields[i].ty(tcx, substs), // Discriminant field for enums (where applicable). - Variants::Multiple { ref discr, .. } => { + Variants::Multiple { ref tag, .. } => { assert_eq!(i, 0); - return discr_layout(discr); + return tag_layout(tag); } } } @@ -2208,10 +2208,10 @@ where // using more niches than just null (e.g., the first page of // the address space, or unaligned pointers). Variants::Multiple { - discr_kind: DiscriminantKind::Niche { dataful_variant, .. }, - discr_index, + tag_encoding: TagEncoding::Niche { dataful_variant, .. }, + tag_field, .. - } if this.fields.offset(discr_index) == offset => { + } if this.fields.offset(tag_field) == offset => { Some(this.for_variant(cx, dataful_variant)) } _ => Some(this), diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index db4473154c47..7da50eaa3e39 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer}; use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; -use rustc_target::abi::{Abi, DiscriminantKind, HasDataLayout, LayoutOf, Size}; +use rustc_target::abi::{Abi, TagEncoding, HasDataLayout, LayoutOf, Size}; use rustc_target::abi::{VariantIdx, Variants}; use super::{ @@ -587,7 +587,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { op: OpTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, (Scalar, VariantIdx)> { trace!("read_discriminant_value {:#?}", op.layout); - // Get type and layout of the discriminant. let discr_layout = self.layout_of(op.layout.ty.discriminant_ty(*self.tcx))?; trace!("discriminant type: {:?}", discr_layout.ty); @@ -596,10 +595,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // This is not to be confused with its "variant index", which is just determining its position in the // declared list of variants -- they can differ with explicitly assigned discriminants. // We use "tag" to refer to how the discriminant is encoded in memory, which can be either - // straight-forward (`DiscriminantKind::Tag`) or with a niche (`DiscriminantKind::Niche`). - // Unfortunately, the rest of the compiler calls the latter "discriminant", too, which makes things - // rather confusing. - let (tag_scalar_layout, tag_kind, tag_index) = match op.layout.variants { + // straight-forward (`TagEncoding::Direct`) or with a niche (`TagEncoding::Niche`). + let (tag_scalar_layout, tag_encoding, tag_field) = match op.layout.variants { Variants::Single { index } => { let discr = match op.layout.ty.discriminant_for_variant(*self.tcx, index) { Some(discr) => { @@ -615,8 +612,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; return Ok((discr, index)); } - Variants::Multiple { ref discr, ref discr_kind, discr_index, .. } => { - (discr, discr_kind, discr_index) + Variants::Multiple { ref tag, ref tag_encoding, tag_field, .. } => { + (tag, tag_encoding, tag_field) } }; @@ -633,21 +630,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let tag_layout = self.layout_of(tag_scalar_layout.value.to_int_ty(*self.tcx))?; // Read tag and sanity-check `tag_layout`. - let tag_val = self.read_immediate(self.operand_field(op, tag_index)?)?; + let tag_val = self.read_immediate(self.operand_field(op, tag_field)?)?; assert_eq!(tag_layout.size, tag_val.layout.size); assert_eq!(tag_layout.abi.is_signed(), tag_val.layout.abi.is_signed()); let tag_val = tag_val.to_scalar()?; trace!("tag value: {:?}", tag_val); // Figure out which discriminant and variant this corresponds to. - Ok(match *tag_kind { - DiscriminantKind::Tag => { + Ok(match *tag_encoding { + TagEncoding::Direct => { let tag_bits = self .force_bits(tag_val, tag_layout.size) .map_err(|_| err_ub!(InvalidDiscriminant(tag_val.erase_tag())))?; // Cast bits from tag layout to discriminant layout. - let discr_val_cast = self.cast_from_scalar(tag_bits, tag_layout, discr_layout.ty); - let discr_bits = discr_val_cast.assert_bits(discr_layout.size); + let discr_val = self.cast_from_scalar(tag_bits, tag_layout, discr_layout.ty); + let discr_bits = discr_val.assert_bits(discr_layout.size); // Convert discriminant to variant index, and catch invalid discriminants. let index = match op.layout.ty.kind { ty::Adt(adt, _) => { @@ -663,9 +660,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } .ok_or_else(|| err_ub!(InvalidDiscriminant(tag_val.erase_tag())))?; // Return the cast value, and the index. - (discr_val_cast, index.0) + (discr_val, index.0) } - DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start } => { + TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => { // Compute the variant this niche value/"tag" corresponds to. With niche layout, // discriminant (encoded in niche/tag) and variant index are the same. let variants_start = niche_variants.start().as_u32(); diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 3f0800b12b54..1e6335c871e7 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -9,7 +9,7 @@ use rustc_macros::HashStable; use rustc_middle::mir; use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout}; use rustc_middle::ty::{self, Ty}; -use rustc_target::abi::{Abi, Align, DiscriminantKind, FieldsShape}; +use rustc_target::abi::{Abi, Align, FieldsShape, TagEncoding}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, VariantIdx, Variants}; use super::{ @@ -1031,7 +1031,8 @@ where MPlaceTy { mplace, layout } } - pub fn write_discriminant_index( + /// Writes the discriminant of the given variant. + pub fn write_discriminant( &mut self, variant_index: VariantIdx, dest: PlaceTy<'tcx, M::PointerTag>, @@ -1047,9 +1048,9 @@ where assert_eq!(index, variant_index); } Variants::Multiple { - discr_kind: DiscriminantKind::Tag, - discr: ref discr_layout, - discr_index, + tag_encoding: TagEncoding::Direct, + tag: ref tag_layout, + tag_field, .. } => { // No need to validate that the discriminant here because the @@ -1061,17 +1062,17 @@ where // raw discriminants for enums are isize or bigger during // their computation, but the in-memory tag is the smallest possible // representation - let size = discr_layout.value.size(self); - let discr_val = truncate(discr_val, size); + let size = tag_layout.value.size(self); + let tag_val = truncate(discr_val, size); - let discr_dest = self.place_field(dest, discr_index)?; - self.write_scalar(Scalar::from_uint(discr_val, size), discr_dest)?; + let tag_dest = self.place_field(dest, tag_field)?; + self.write_scalar(Scalar::from_uint(tag_val, size), tag_dest)?; } Variants::Multiple { - discr_kind: - DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start }, - discr: ref discr_layout, - discr_index, + tag_encoding: + TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start }, + tag: ref tag_layout, + tag_field, .. } => { // No need to validate that the discriminant here because the @@ -1084,19 +1085,19 @@ where .checked_sub(variants_start) .expect("overflow computing relative variant idx"); // We need to use machine arithmetic when taking into account `niche_start`: - // discr_val = variant_index_relative + niche_start_val - let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?; - let niche_start_val = ImmTy::from_uint(niche_start, discr_layout); + // tag_val = variant_index_relative + niche_start_val + let tag_layout = self.layout_of(tag_layout.value.to_int_ty(*self.tcx))?; + let niche_start_val = ImmTy::from_uint(niche_start, tag_layout); let variant_index_relative_val = - ImmTy::from_uint(variant_index_relative, discr_layout); - let discr_val = self.binary_op( + ImmTy::from_uint(variant_index_relative, tag_layout); + let tag_val = self.binary_op( mir::BinOp::Add, variant_index_relative_val, niche_start_val, )?; // Write result. - let niche_dest = self.place_field(dest, discr_index)?; - self.write_immediate(*discr_val, niche_dest)?; + let niche_dest = self.place_field(dest, tag_field)?; + self.write_immediate(*tag_val, niche_dest)?; } } } diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index bd4df788057e..029b83492d59 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -89,7 +89,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { SetDiscriminant { place, variant_index } => { let dest = self.eval_place(**place)?; - self.write_discriminant_index(*variant_index, dest)?; + self.write_discriminant(*variant_index, dest)?; } // Mark locals as alive @@ -174,7 +174,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Aggregate(ref kind, ref operands) => { let (dest, active_field_index) = match **kind { mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => { - self.write_discriminant_index(variant_index, dest)?; + self.write_discriminant(variant_index, dest)?; if adt_def.is_enum() { (self.place_downcast(dest, variant_index)?, active_field_index) } else { diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index e962dfb2b3e8..f21a96a97909 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -208,8 +208,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize) -> PathElem { // First, check if we are projecting to a variant. match layout.variants { - Variants::Multiple { discr_index, .. } => { - if discr_index == field { + Variants::Multiple { tag_field, .. } => { + if tag_field == field { return match layout.ty.kind { ty::Adt(def, ..) if def.is_enum() => PathElem::EnumTag, ty::Generator(..) => PathElem::GeneratorTag, diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index dcf181cb59f4..c79e9bb28900 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -809,25 +809,30 @@ pub enum Variants { /// Single enum variants, structs/tuples, unions, and all non-ADTs. Single { index: VariantIdx }, - /// Enum-likes with more than one inhabited variant: for each case there is - /// a struct, and they all have space reserved for the discriminant. - /// For enums this is the sole field of the layout. + /// Enum-likes with more than one inhabited variant: each variant comes with + /// a *discriminant* (usually the same as the variant index but the user can + /// assign explicit discriminant values). That discriminant is encoded + /// as a *tag* on the machine. The layout of each variant is + /// a struct, and they all have space reserved for the tag. + /// For enums, the tag is the sole field of the layout. Multiple { - discr: Scalar, - discr_kind: DiscriminantKind, - discr_index: usize, + tag: Scalar, + tag_encoding: TagEncoding, + tag_field: usize, variants: IndexVec, }, } #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] -pub enum DiscriminantKind { - /// Integer tag holding the discriminant value itself. - Tag, +pub enum TagEncoding { + /// The tag directly stores the discriminant, but possibly with a smaller layout + /// (so converting the tag to the discriminant can require sign extension). + Direct, /// Niche (values invalid for a type) encoding the discriminant: - /// the variant `dataful_variant` contains a niche at an arbitrary - /// offset (field `discr_index` of the enum), which for a variant with + /// Discriminant and variant index coincide. + /// The variant `dataful_variant` contains a niche at an arbitrary + /// offset (field `tag_field` of the enum), which for a variant with /// discriminant `d` is set to /// `(d - niche_variants.start).wrapping_add(niche_start)`. /// diff --git a/src/test/ui/layout/debug.stderr b/src/test/ui/layout/debug.stderr index cd8ebdffb730..1a371c6b1700 100644 --- a/src/test/ui/layout/debug.stderr +++ b/src/test/ui/layout/debug.stderr @@ -10,15 +10,15 @@ error: layout_of(E) = Layout { ], }, variants: Multiple { - discr: Scalar { + tag: Scalar { value: Int( I32, false, ), valid_range: 0..=0, }, - discr_kind: Tag, - discr_index: 0, + tag_encoding: Direct, + tag_field: 0, variants: [ Layout { fields: Arbitrary { @@ -202,15 +202,15 @@ error: layout_of(std::result::Result) = Layout { ], }, variants: Multiple { - discr: Scalar { + tag: Scalar { value: Int( I32, false, ), valid_range: 0..=1, }, - discr_kind: Tag, - discr_index: 0, + tag_encoding: Direct, + tag_field: 0, variants: [ Layout { fields: Arbitrary {