Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions compiler/rustc_abi/src/layout.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::BTreeSet;
use std::fmt::{self, Write};
use std::ops::Deref;
use std::range::RangeInclusive;
use std::{cmp, iter};

use rustc_hashes::Hash64;
Expand Down Expand Up @@ -631,11 +632,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
let all_indices = variants.indices();
let needs_disc =
|index: VariantIdx| index != largest_variant_index && !absent(&variants[index]);
let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap()
..=all_indices.rev().find(|v| needs_disc(*v)).unwrap();
let niche_variants = RangeInclusive {
start: all_indices.clone().find(|v| needs_disc(*v)).unwrap(),
last: all_indices.rev().find(|v| needs_disc(*v)).unwrap(),
};

let count =
(niche_variants.end().index() as u128 - niche_variants.start().index() as u128) + 1;
(niche_variants.last.index() as u128 - niche_variants.start.index() as u128) + 1;

// Use the largest niche in the largest variant.
let niche = variant_layouts[largest_variant_index].largest_niche?;
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ use std::fmt;
#[cfg(feature = "nightly")]
use std::iter::Step;
use std::num::{NonZeroUsize, ParseIntError};
use std::ops::{Add, AddAssign, Deref, Mul, RangeFull, RangeInclusive, Sub};
use std::ops::{Add, AddAssign, Deref, Mul, RangeFull, Sub};
use std::range::RangeInclusive;
use std::str::FromStr;

use bitflags::bitflags;
Expand Down Expand Up @@ -1958,7 +1959,7 @@ pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
}

// NOTE: This struct is generic over the VariantIdx for rust-analyzer usage.
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
#[cfg_attr(feature = "nightly", derive(StableHash))]
pub enum TagEncoding<VariantIdx: Idx> {
/// The tag directly stores the discriminant, but possibly with a smaller layout
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_cranelift/src/discriminant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
if variant_index != untagged_variant {
let niche = place.place_field(fx, tag_field);
let niche_type = fx.clif_type(niche.layout().ty).unwrap();
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
let niche_value = variant_index.as_u32() - niche_variants.start.as_u32();
let niche_value = (niche_value as u128).wrapping_add(niche_start);
let niche_value = match niche_type {
types::I128 => {
Expand Down Expand Up @@ -133,7 +133,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
dest.write_cvalue(fx, res);
}
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
let relative_max = niche_variants.last.as_u32() - niche_variants.start.as_u32();

// We have a subrange `niche_start..=niche_end` inside `range`.
// If the value of the tag is inside this subrange, it's a
Expand Down Expand Up @@ -162,7 +162,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
// }
let is_niche = codegen_icmp_imm(fx, IntCC::Equal, tag, niche_start as i128);
let tagged_discr =
fx.bcx.ins().iconst(cast_to, niche_variants.start().as_u32() as i64);
fx.bcx.ins().iconst(cast_to, niche_variants.start.as_u32() as i64);
(is_niche, tagged_discr, 0)
} else {
// The special cases don't apply, so we'll have to go with
Expand All @@ -184,7 +184,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
relative_discr,
i128::from(relative_max),
);
(is_niche, cast_tag, niche_variants.start().as_u32() as u128)
(is_niche, cast_tag, niche_variants.start.as_u32() as u128)
};

let tagged_discr = if delta == 0 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ fn compute_discriminant_value<'ll, 'tcx>(
DiscrResult::Range(min, max)
} else {
let value = (variant_index.as_u32() as u128)
.wrapping_sub(niche_variants.start().as_u32() as u128)
.wrapping_sub(niche_variants.start.as_u32() as u128)
.wrapping_add(niche_start);
let value = tag.size(cx).truncate(value);
DiscrResult::Value(value)
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_ssa/src/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
// `layout_sanity_check` ensures that we only get here for cases where the discriminant
// value and the variant index match, since that's all `Niche` can encode.

let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
let relative_max = niche_variants.last.as_u32() - niche_variants.start.as_u32();
let niche_start_const = bx.cx().const_uint_big(tag_llty, niche_start);

// We have a subrange `niche_start..=niche_end` inside `range`.
Expand Down Expand Up @@ -523,7 +523,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
// }
let is_niche = bx.icmp(IntPredicate::IntEQ, tag, niche_start_const);
let tagged_discr =
bx.cx().const_uint(cast_to, niche_variants.start().as_u32() as u64);
bx.cx().const_uint(cast_to, niche_variants.start.as_u32() as u64);
(is_niche, tagged_discr, 0)
} else {
// Thanks to parameter attributes and load metadata, LLVM already knows
Expand All @@ -549,7 +549,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
{
let impossible = niche_start
.wrapping_add(u128::from(untagged_variant.as_u32()))
.wrapping_sub(u128::from(niche_variants.start().as_u32()));
.wrapping_sub(u128::from(niche_variants.start.as_u32()));
let impossible = bx.cx().const_uint_big(tag_llty, impossible);
let ne = bx.icmp(IntPredicate::IntNE, tag, impossible);
bx.assume(ne);
Expand Down Expand Up @@ -633,7 +633,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
)
};

(is_niche, cast_tag, niche_variants.start().as_u32() as u128)
(is_niche, cast_tag, niche_variants.start.as_u32() as u128)
};

let tagged_discr = if delta == 0 {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ pub(super) fn codegen_tag_value<'tcx, V>(
// around the `niche`'s type.
// The easiest way to do that is to do wrapping arithmetic on `u128` and then
// masking off any extra bits that occur because we did the arithmetic with too many bits.
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
let niche_value = variant_index.as_u32() - niche_variants.start.as_u32();
let niche_value = (niche_value as u128).wrapping_add(niche_start);
let niche_value = niche_value & niche_layout.size.unsigned_int_max();

Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_const_eval/src/interpret/discriminant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,16 +142,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let tag_val = tag_val.to_scalar();
// 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();
let variants_end = niche_variants.end().as_u32();
let variants_start = niche_variants.start.as_u32();
let variants_last = niche_variants.last.as_u32();
let variant = match tag_val.try_to_scalar_int() {
Err(dbg_val) => {
// So this is a pointer then, and casting to an int failed.
// Can only happen during CTFE.
// The niche must be just 0, and the ptr not null, then we know this is
// okay. Everything else, we conservatively reject.
let ptr_valid = niche_start == 0
&& variants_start == variants_end
&& variants_start == variants_last
&& !self.scalar_may_be_null(tag_val)?;
if !ptr_valid {
throw_ub!(InvalidTag(dbg_val))
Expand All @@ -169,7 +169,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let variant_index_relative =
variant_index_relative_val.to_scalar().to_bits(tag_val.layout.size)?;
// Check if this is in the range that indicates an actual discriminant.
if variant_index_relative <= u128::from(variants_end - variants_start) {
if variant_index_relative <= u128::from(variants_last - variants_start) {
let variant_index_relative = u32::try_from(variant_index_relative)
.expect("we checked that this fits into a u32");
// Then computing the absolute variant idx should not overflow any more.
Expand Down Expand Up @@ -309,7 +309,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
niche_variants.contains(&variant_index),
"invalid variant index for this enum"
);
let variants_start = niche_variants.start().as_u32();
let variants_start = niche_variants.start.as_u32();
let variant_index_relative = variant_index.as_u32().strict_sub(variants_start);
// We need to use machine arithmetic when taking into account `niche_start`:
// tag_val = variant_index_relative + niche_start_val
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_data_structures/src/stable_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,14 +527,14 @@ impl<T> StableHash for ::std::mem::Discriminant<T> {
}
}

impl<T> StableHash for ::std::ops::RangeInclusive<T>
impl<T> StableHash for ::std::range::RangeInclusive<T>
where
T: StableHash,
{
#[inline]
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
self.start().stable_hash(hcx, hasher);
self.end().stable_hash(hcx, hasher);
self.start.stable_hash(hcx, hasher);
self.last.stable_hash(hcx, hasher);
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ where
} else {
VariantIdx::from_u32(0)
};
assert_eq!(tagged_variant, *niche_variants.start());
assert_eq!(tagged_variant, niche_variants.start);
if *niche_start == 0 {
// The other variant is encoded as "null", so we can recurse searching for
// a pointer here. This relies on the fact that the codegen backend
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_public/src/unstable/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//! For contributors, please make sure to avoid calling rustc's internal functions and queries.
//! These should be done via `rustc_public_bridge` APIs, but it's possible to access ADT fields directly.

use std::ops::RangeInclusive;
use std::{ops, range};

use rustc_public_bridge::Tables;
use rustc_public_bridge::context::CompilerCtxt;
Expand Down Expand Up @@ -95,16 +95,16 @@ where
}
}

impl<'tcx, T> Stable<'tcx> for RangeInclusive<T>
impl<'tcx, T> Stable<'tcx> for range::RangeInclusive<T>
where
T: Stable<'tcx>,
{
type T = RangeInclusive<T::T>;
type T = ops::RangeInclusive<T::T>;
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
RangeInclusive::new(self.start().stable(tables, cx), self.end().stable(tables, cx))
ops::RangeInclusive::new(self.start.stable(tables, cx), self.last.stable(tables, cx))
}
}
8 changes: 4 additions & 4 deletions compiler/rustc_transmute/src/layout/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,12 +421,12 @@ pub(crate) mod rustc {
)
};

match layout.variants() {
match *layout.variants() {
Variants::Empty => Ok(Self::uninhabited()),
Variants::Single { index } => {
// `Variants::Single` on enums with variants denotes that
// the enum delegates its layout to the variant at `index`.
layout_of_variant(*index, None)
layout_of_variant(index, None)
}
Variants::Multiple { tag: _, tag_encoding, tag_field, .. } => {
// `Variants::Multiple` denotes an enum with multiple
Expand All @@ -435,12 +435,12 @@ pub(crate) mod rustc {

// For enums (but not coroutines), the tag field is
// currently always the first field of the layout.
assert_eq!(*tag_field, FieldIdx::ZERO);
assert_eq!(tag_field, FieldIdx::ZERO);

let variants = def.discriminants(cx.tcx()).try_fold(
Self::uninhabited(),
|variants, (idx, _discriminant)| {
let variant = layout_of_variant(idx, Some(tag_encoding.clone()))?;
let variant = layout_of_variant(idx, Some(tag_encoding))?;
Result::<Self, Err>::Ok(variants.or(variant))
},
)?;
Expand Down
Loading