Auto merge of #98957 - RalfJung:zst-are-different, r=lcnr,oli-obk
don't allow ZST in ScalarInt There are several indications that we should not ZST as a ScalarInt: - We had two ways to have ZST valtrees, either an empty `Branch` or a `Leaf` with a ZST in it. `ValTree::zst()` used the former, but the latter could possibly arise as well. - Likewise, the interpreter had `Immediate::Uninit` and `Immediate::Scalar(Scalar::ZST)`. - LLVM codegen already had to special-case ZST ScalarInt. So I propose we stop using ScalarInt to represent ZST (which are clearly not integers). Instead, we can add new ZST variants to those types that did not have other variants which could be used for this purpose. Based on https://github.com/rust-lang/rust/pull/98831. Only the commits starting from "don't allow ZST in ScalarInt" are new. r? `@oli-obk`
This commit is contained in:
@@ -29,11 +29,14 @@ pub struct ConstAlloc<'tcx> {
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
|
||||
#[derive(HashStable)]
|
||||
pub enum ConstValue<'tcx> {
|
||||
/// Used only for types with `layout::abi::Scalar` ABI and ZSTs.
|
||||
/// Used only for types with `layout::abi::Scalar` ABI.
|
||||
///
|
||||
/// Not using the enum `Value` to encode that this must not be `Uninit`.
|
||||
Scalar(Scalar),
|
||||
|
||||
/// Only used for ZSTs.
|
||||
ZeroSized,
|
||||
|
||||
/// Used only for `&[u8]` and `&str`
|
||||
Slice { data: ConstAllocation<'tcx>, start: usize, end: usize },
|
||||
|
||||
@@ -55,6 +58,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ConstValue<'tcx>> {
|
||||
Some(match self {
|
||||
ConstValue::Scalar(s) => ConstValue::Scalar(s),
|
||||
ConstValue::ZeroSized => ConstValue::ZeroSized,
|
||||
ConstValue::Slice { data, start, end } => {
|
||||
ConstValue::Slice { data: tcx.lift(data)?, start, end }
|
||||
}
|
||||
@@ -69,7 +73,7 @@ impl<'tcx> ConstValue<'tcx> {
|
||||
#[inline]
|
||||
pub fn try_to_scalar(&self) -> Option<Scalar<AllocId>> {
|
||||
match *self {
|
||||
ConstValue::ByRef { .. } | ConstValue::Slice { .. } => None,
|
||||
ConstValue::ByRef { .. } | ConstValue::Slice { .. } | ConstValue::ZeroSized => None,
|
||||
ConstValue::Scalar(val) => Some(val),
|
||||
}
|
||||
}
|
||||
@@ -111,10 +115,6 @@ impl<'tcx> ConstValue<'tcx> {
|
||||
pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self {
|
||||
ConstValue::Scalar(Scalar::from_machine_usize(i, cx))
|
||||
}
|
||||
|
||||
pub fn zst() -> Self {
|
||||
Self::Scalar(Scalar::ZST)
|
||||
}
|
||||
}
|
||||
|
||||
/// A `Scalar` represents an immediate, primitive value existing outside of a
|
||||
@@ -194,8 +194,6 @@ impl<Tag> From<ScalarInt> for Scalar<Tag> {
|
||||
}
|
||||
|
||||
impl<Tag> Scalar<Tag> {
|
||||
pub const ZST: Self = Scalar::Int(ScalarInt::ZST);
|
||||
|
||||
#[inline(always)]
|
||||
pub fn from_pointer(ptr: Pointer<Tag>, cx: &impl HasDataLayout) -> Self {
|
||||
Scalar::Ptr(ptr, u8::try_from(cx.pointer_size().bytes()).unwrap())
|
||||
|
||||
@@ -1711,7 +1711,7 @@ impl<'tcx> Operand<'tcx> {
|
||||
Operand::Constant(Box::new(Constant {
|
||||
span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::Val(ConstValue::zst(), ty),
|
||||
literal: ConstantKind::Val(ConstValue::ZeroSized, ty),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -2196,7 +2196,7 @@ impl<'tcx> ConstantKind<'tcx> {
|
||||
|
||||
#[inline]
|
||||
pub fn zero_sized(ty: Ty<'tcx>) -> Self {
|
||||
let cv = ConstValue::Scalar(Scalar::ZST);
|
||||
let cv = ConstValue::ZeroSized;
|
||||
Self::Val(cv, ty)
|
||||
}
|
||||
|
||||
@@ -2772,6 +2772,13 @@ fn pretty_print_const_value<'tcx>(
|
||||
fmt.write_str(&cx.into_buffer())?;
|
||||
return Ok(());
|
||||
}
|
||||
(ConstValue::ZeroSized, ty::FnDef(d, s)) => {
|
||||
let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
|
||||
cx.print_alloc_ids = true;
|
||||
let cx = cx.print_value_path(*d, s)?;
|
||||
fmt.write_str(&cx.into_buffer())?;
|
||||
return Ok(());
|
||||
}
|
||||
// FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
|
||||
// their fields instead of just dumping the memory.
|
||||
_ => {}
|
||||
|
||||
@@ -448,7 +448,9 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
|
||||
self.push(&format!("+ user_ty: {:?}", user_ty));
|
||||
}
|
||||
|
||||
// FIXME: this is a poor version of `pretty_print_const_value`.
|
||||
let fmt_val = |val: &ConstValue<'tcx>| match val {
|
||||
ConstValue::ZeroSized => format!("<ZST>"),
|
||||
ConstValue::Scalar(s) => format!("Scalar({:?})", s),
|
||||
ConstValue::Slice { .. } => format!("Slice(..)"),
|
||||
ConstValue::ByRef { .. } => format!("ByRef(..)"),
|
||||
@@ -679,6 +681,7 @@ pub fn write_allocations<'tcx>(
|
||||
ConstValue::Scalar(interpret::Scalar::Int { .. }) => {
|
||||
Either::Left(Either::Right(std::iter::empty()))
|
||||
}
|
||||
ConstValue::ZeroSized => Either::Left(Either::Right(std::iter::empty())),
|
||||
ConstValue::ByRef { alloc, .. } | ConstValue::Slice { data: alloc, .. } => {
|
||||
Either::Right(alloc_ids_from_alloc(alloc))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user