1
Fork 0

make read_immediate error immediately on uninit, so ImmTy can carry initialized Scalar

This commit is contained in:
Ralf Jung 2022-08-01 19:05:20 -04:00
parent 2e52fe01cf
commit 30fa931f92
51 changed files with 491 additions and 747 deletions

View file

@ -3,7 +3,7 @@ use crate::interpret::eval_nullary_intrinsic;
use crate::interpret::{ use crate::interpret::{
intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId, intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId,
Immediate, InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, Immediate, InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking,
ScalarMaybeUninit, StackPopCleanup, StackPopCleanup,
}; };
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
@ -170,10 +170,7 @@ pub(super) fn op_to_const<'tcx>(
// see comment on `let try_as_immediate` above // see comment on `let try_as_immediate` above
Err(imm) => match *imm { Err(imm) => match *imm {
_ if imm.layout.is_zst() => ConstValue::ZeroSized, _ if imm.layout.is_zst() => ConstValue::ZeroSized,
Immediate::Scalar(x) => match x { Immediate::Scalar(x) => ConstValue::Scalar(x),
ScalarMaybeUninit::Scalar(s) => ConstValue::Scalar(s),
ScalarMaybeUninit::Uninit => to_const_value(&op.assert_mem_place()),
},
Immediate::ScalarPair(a, b) => { Immediate::ScalarPair(a, b) => {
debug!("ScalarPair(a: {:?}, b: {:?})", a, b); debug!("ScalarPair(a: {:?}, b: {:?})", a, b);
// We know `offset` is relative to the allocation, so we can use `into_parts`. // We know `offset` is relative to the allocation, so we can use `into_parts`.

View file

@ -347,8 +347,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
}; };
match intrinsic_name { match intrinsic_name {
sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => { sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => {
let a = ecx.read_immediate(&args[0])?.to_scalar()?; let a = ecx.read_scalar(&args[0])?;
let b = ecx.read_immediate(&args[1])?.to_scalar()?; let b = ecx.read_scalar(&args[1])?;
let cmp = if intrinsic_name == sym::ptr_guaranteed_eq { let cmp = if intrinsic_name == sym::ptr_guaranteed_eq {
ecx.guaranteed_eq(a, b)? ecx.guaranteed_eq(a, b)?
} else { } else {

View file

@ -3,7 +3,7 @@ use super::machine::CompileTimeEvalContext;
use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES}; use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES};
use crate::interpret::{ use crate::interpret::{
intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta, intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta,
MemoryKind, PlaceTy, Scalar, ScalarMaybeUninit, MemoryKind, PlaceTy, Scalar,
}; };
use crate::interpret::{MPlaceTy, Value}; use crate::interpret::{MPlaceTy, Value};
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
@ -90,7 +90,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
let Ok(val) = ecx.read_immediate(&place.into()) else { let Ok(val) = ecx.read_immediate(&place.into()) else {
return Err(ValTreeCreationError::Other); return Err(ValTreeCreationError::Other);
}; };
let val = val.to_scalar().unwrap(); let val = val.to_scalar();
*num_nodes += 1; *num_nodes += 1;
Ok(ty::ValTree::Leaf(val.assert_int())) Ok(ty::ValTree::Leaf(val.assert_int()))
@ -349,11 +349,7 @@ fn valtree_into_mplace<'tcx>(
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => { ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
let scalar_int = valtree.unwrap_leaf(); let scalar_int = valtree.unwrap_leaf();
debug!("writing trivial valtree {:?} to place {:?}", scalar_int, place); debug!("writing trivial valtree {:?} to place {:?}", scalar_int, place);
ecx.write_immediate( ecx.write_immediate(Immediate::Scalar(scalar_int.into()), &place.into()).unwrap();
Immediate::Scalar(ScalarMaybeUninit::Scalar(scalar_int.into())),
&place.into(),
)
.unwrap();
} }
ty::Ref(_, inner_ty, _) => { ty::Ref(_, inner_ty, _) => {
let mut pointee_place = create_pointee_place(ecx, *inner_ty, valtree); let mut pointee_place = create_pointee_place(ecx, *inner_ty, valtree);
@ -366,11 +362,10 @@ fn valtree_into_mplace<'tcx>(
let imm = match inner_ty.kind() { let imm = match inner_ty.kind() {
ty::Slice(_) | ty::Str => { ty::Slice(_) | ty::Str => {
let len = valtree.unwrap_branch().len(); let len = valtree.unwrap_branch().len();
let len_scalar = let len_scalar = Scalar::from_machine_usize(len as u64, &tcx);
ScalarMaybeUninit::Scalar(Scalar::from_machine_usize(len as u64, &tcx));
Immediate::ScalarPair( Immediate::ScalarPair(
ScalarMaybeUninit::from_maybe_pointer((*pointee_place).ptr, &tcx), Scalar::from_maybe_pointer((*pointee_place).ptr, &tcx),
len_scalar, len_scalar,
) )
} }

View file

@ -123,10 +123,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match src.layout.ty.kind() { match src.layout.ty.kind() {
// Floating point // Floating point
Float(FloatTy::F32) => { Float(FloatTy::F32) => {
return Ok(self.cast_from_float(src.to_scalar()?.to_f32()?, cast_ty).into()); return Ok(self.cast_from_float(src.to_scalar().to_f32()?, cast_ty).into());
} }
Float(FloatTy::F64) => { Float(FloatTy::F64) => {
return Ok(self.cast_from_float(src.to_scalar()?.to_f64()?, cast_ty).into()); return Ok(self.cast_from_float(src.to_scalar().to_f64()?, cast_ty).into());
} }
// The rest is integer/pointer-"like", including fn ptr casts // The rest is integer/pointer-"like", including fn ptr casts
_ => assert!( _ => assert!(
@ -153,7 +153,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert_eq!(dest_layout.size, self.pointer_size()); assert_eq!(dest_layout.size, self.pointer_size());
assert!(src.layout.ty.is_unsafe_ptr()); assert!(src.layout.ty.is_unsafe_ptr());
return match **src { return match **src {
Immediate::ScalarPair(data, _) => Ok(data.check_init()?.into()), Immediate::ScalarPair(data, _) => Ok(data.into()),
Immediate::Scalar(..) => span_bug!( Immediate::Scalar(..) => span_bug!(
self.cur_span(), self.cur_span(),
"{:?} input to a fat-to-thin cast ({:?} -> {:?})", "{:?} input to a fat-to-thin cast ({:?} -> {:?})",
@ -167,7 +167,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
// # The remaining source values are scalar and "int-like". // # The remaining source values are scalar and "int-like".
let scalar = src.to_scalar()?; let scalar = src.to_scalar();
Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into()) Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into())
} }
@ -179,7 +179,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert_matches!(src.layout.ty.kind(), ty::RawPtr(_) | ty::FnPtr(_)); assert_matches!(src.layout.ty.kind(), ty::RawPtr(_) | ty::FnPtr(_));
assert!(cast_ty.is_integral()); assert!(cast_ty.is_integral());
let scalar = src.to_scalar()?; let scalar = src.to_scalar();
let ptr = scalar.to_pointer(self)?; let ptr = scalar.to_pointer(self)?;
match ptr.into_pointer_or_addr() { match ptr.into_pointer_or_addr() {
Ok(ptr) => M::expose_ptr(self, ptr)?, Ok(ptr) => M::expose_ptr(self, ptr)?,
@ -197,7 +197,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert_matches!(cast_ty.kind(), ty::RawPtr(_)); assert_matches!(cast_ty.kind(), ty::RawPtr(_));
// First cast to usize. // First cast to usize.
let scalar = src.to_scalar()?; let scalar = src.to_scalar();
let addr = self.cast_from_int_like(scalar, src.layout, self.tcx.types.usize)?; let addr = self.cast_from_int_like(scalar, src.layout, self.tcx.types.usize)?;
let addr = addr.to_machine_usize(self)?; let addr = addr.to_machine_usize(self)?;
@ -291,7 +291,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) { match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) {
(&ty::Array(_, length), &ty::Slice(_)) => { (&ty::Array(_, length), &ty::Slice(_)) => {
let ptr = self.read_immediate(src)?.to_scalar()?; let ptr = self.read_scalar(src)?;
// u64 cast is from usize to u64, which is always good // u64 cast is from usize to u64, which is always good
let val = let val =
Immediate::new_slice(ptr, length.eval_usize(*self.tcx, self.param_env), self); Immediate::new_slice(ptr, length.eval_usize(*self.tcx, self.param_env), self);
@ -303,7 +303,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// A NOP cast that doesn't actually change anything, should be allowed even with mismatching vtables. // A NOP cast that doesn't actually change anything, should be allowed even with mismatching vtables.
return self.write_immediate(*val, dest); return self.write_immediate(*val, dest);
} }
let (old_data, old_vptr) = val.to_scalar_pair()?; let (old_data, old_vptr) = val.to_scalar_pair();
let old_vptr = old_vptr.to_pointer(self)?; let old_vptr = old_vptr.to_pointer(self)?;
let (ty, old_trait) = self.get_ptr_vtable(old_vptr)?; let (ty, old_trait) = self.get_ptr_vtable(old_vptr)?;
if old_trait != data_a.principal() { if old_trait != data_a.principal() {
@ -315,7 +315,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
(_, &ty::Dynamic(ref data, _)) => { (_, &ty::Dynamic(ref data, _)) => {
// Initial cast from sized to dyn trait // Initial cast from sized to dyn trait
let vtable = self.get_vtable_ptr(src_pointee_ty, data.principal())?; let vtable = self.get_vtable_ptr(src_pointee_ty, data.principal())?;
let ptr = self.read_immediate(src)?.to_scalar()?; let ptr = self.read_scalar(src)?;
let val = Immediate::new_dyn_trait(ptr, vtable, &*self.tcx); let val = Immediate::new_dyn_trait(ptr, vtable, &*self.tcx);
self.write_immediate(val, dest) self.write_immediate(val, dest)
} }

View file

@ -21,7 +21,7 @@ use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayou
use super::{ use super::{
AllocId, GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, AllocId, GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace,
MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, PointerArithmetic, Provenance, MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, PointerArithmetic, Provenance,
Scalar, ScalarMaybeUninit, StackPopJump, Scalar, StackPopJump,
}; };
use crate::transform::validate::equal_up_to_regions; use crate::transform::validate::equal_up_to_regions;
@ -991,16 +991,16 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug
} }
LocalValue::Live(Operand::Immediate(Immediate::Scalar(val))) => { LocalValue::Live(Operand::Immediate(Immediate::Scalar(val))) => {
write!(fmt, " {:?}", val)?; write!(fmt, " {:?}", val)?;
if let ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, _size)) = val { if let Scalar::Ptr(ptr, _size) = val {
allocs.push(ptr.provenance.get_alloc_id()); allocs.push(ptr.provenance.get_alloc_id());
} }
} }
LocalValue::Live(Operand::Immediate(Immediate::ScalarPair(val1, val2))) => { LocalValue::Live(Operand::Immediate(Immediate::ScalarPair(val1, val2))) => {
write!(fmt, " ({:?}, {:?})", val1, val2)?; write!(fmt, " ({:?}, {:?})", val1, val2)?;
if let ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, _size)) = val1 { if let Scalar::Ptr(ptr, _size) = val1 {
allocs.push(ptr.provenance.get_alloc_id()); allocs.push(ptr.provenance.get_alloc_id());
} }
if let ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, _size)) = val2 { if let Scalar::Ptr(ptr, _size) = val2 {
allocs.push(ptr.provenance.get_alloc_id()); allocs.push(ptr.provenance.get_alloc_id());
} }
} }

View file

@ -184,7 +184,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
| sym::bitreverse => { | sym::bitreverse => {
let ty = substs.type_at(0); let ty = substs.type_at(0);
let layout_of = self.layout_of(ty)?; let layout_of = self.layout_of(ty)?;
let val = self.read_scalar(&args[0])?.check_init()?; let val = self.read_scalar(&args[0])?;
let bits = val.to_bits(layout_of.size)?; let bits = val.to_bits(layout_of.size)?;
let kind = match layout_of.abi { let kind = match layout_of.abi {
Abi::Scalar(scalar) => scalar.primitive(), Abi::Scalar(scalar) => scalar.primitive(),
@ -256,7 +256,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, &l, &r)?; let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, &l, &r)?;
if overflowed { if overflowed {
let layout = self.layout_of(substs.type_at(0))?; let layout = self.layout_of(substs.type_at(0))?;
let r_val = r.to_scalar()?.to_bits(layout.size)?; let r_val = r.to_scalar().to_bits(layout.size)?;
if let sym::unchecked_shl | sym::unchecked_shr = intrinsic_name { if let sym::unchecked_shl | sym::unchecked_shr = intrinsic_name {
throw_ub_format!("overflowing shift by {} in `{}`", r_val, intrinsic_name); throw_ub_format!("overflowing shift by {} in `{}`", r_val, intrinsic_name);
} else { } else {
@ -269,9 +269,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW)) // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW)) // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
let layout = self.layout_of(substs.type_at(0))?; let layout = self.layout_of(substs.type_at(0))?;
let val = self.read_scalar(&args[0])?.check_init()?; let val = self.read_scalar(&args[0])?;
let val_bits = val.to_bits(layout.size)?; let val_bits = val.to_bits(layout.size)?;
let raw_shift = self.read_scalar(&args[1])?.check_init()?; let raw_shift = self.read_scalar(&args[1])?;
let raw_shift_bits = raw_shift.to_bits(layout.size)?; let raw_shift_bits = raw_shift.to_bits(layout.size)?;
let width_bits = u128::from(layout.size.bits()); let width_bits = u128::from(layout.size.bits());
let shift_bits = raw_shift_bits % width_bits; let shift_bits = raw_shift_bits % width_bits;
@ -507,7 +507,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.copy_op(&args[0], dest, /*allow_transmute*/ false)?; self.copy_op(&args[0], dest, /*allow_transmute*/ false)?;
} }
sym::assume => { sym::assume => {
let cond = self.read_scalar(&args[0])?.check_init()?.to_bool()?; let cond = self.read_scalar(&args[0])?.to_bool()?;
if !cond { if !cond {
throw_ub_format!("`assume` intrinsic called with `false`"); throw_ub_format!("`assume` intrinsic called with `false`");
} }
@ -570,7 +570,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// term since the sign of the second term can be inferred from this and // term since the sign of the second term can be inferred from this and
// the fact that the operation has overflowed (if either is 0 no // the fact that the operation has overflowed (if either is 0 no
// overflow can occur) // overflow can occur)
let first_term: u128 = l.to_scalar()?.to_bits(l.layout.size)?; let first_term: u128 = l.to_scalar().to_bits(l.layout.size)?;
let first_term_positive = first_term & (1 << (num_bits - 1)) == 0; let first_term_positive = first_term & (1 << (num_bits - 1)) == 0;
if first_term_positive { if first_term_positive {
// Negative overflow not possible since the positive first term // Negative overflow not possible since the positive first term

View file

@ -21,7 +21,6 @@ use rustc_target::abi::{Align, HasDataLayout, Size};
use super::{ use super::{
alloc_range, AllocId, AllocMap, AllocRange, Allocation, CheckInAllocMsg, GlobalAlloc, InterpCx, alloc_range, AllocId, AllocMap, AllocRange, Allocation, CheckInAllocMsg, GlobalAlloc, InterpCx,
InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Provenance, Scalar, InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Provenance, Scalar,
ScalarMaybeUninit,
}; };
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Copy, Clone)]
@ -901,11 +900,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a,
/// Reading and writing. /// Reading and writing.
impl<'tcx, 'a, Prov: Provenance, Extra> AllocRefMut<'a, 'tcx, Prov, Extra> { impl<'tcx, 'a, Prov: Provenance, Extra> AllocRefMut<'a, 'tcx, Prov, Extra> {
/// `range` is relative to this allocation reference, not the base of the allocation. /// `range` is relative to this allocation reference, not the base of the allocation.
pub fn write_scalar( pub fn write_scalar(&mut self, range: AllocRange, val: Scalar<Prov>) -> InterpResult<'tcx> {
&mut self,
range: AllocRange,
val: ScalarMaybeUninit<Prov>,
) -> InterpResult<'tcx> {
let range = self.range.subrange(range); let range = self.range.subrange(range);
debug!("write_scalar at {:?}{range:?}: {val:?}", self.alloc_id); debug!("write_scalar at {:?}{range:?}: {val:?}", self.alloc_id);
Ok(self Ok(self
@ -915,11 +910,7 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRefMut<'a, 'tcx, Prov, Extra> {
} }
/// `offset` is relative to this allocation reference, not the base of the allocation. /// `offset` is relative to this allocation reference, not the base of the allocation.
pub fn write_ptr_sized( pub fn write_ptr_sized(&mut self, offset: Size, val: Scalar<Prov>) -> InterpResult<'tcx> {
&mut self,
offset: Size,
val: ScalarMaybeUninit<Prov>,
) -> InterpResult<'tcx> {
self.write_scalar(alloc_range(offset, self.tcx.data_layout().pointer_size), val) self.write_scalar(alloc_range(offset, self.tcx.data_layout().pointer_size), val)
} }
@ -938,7 +929,7 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRef<'a, 'tcx, Prov, Extra> {
&self, &self,
range: AllocRange, range: AllocRange,
read_provenance: bool, read_provenance: bool,
) -> InterpResult<'tcx, ScalarMaybeUninit<Prov>> { ) -> InterpResult<'tcx, Scalar<Prov>> {
let range = self.range.subrange(range); let range = self.range.subrange(range);
let res = self let res = self
.alloc .alloc
@ -949,12 +940,12 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRef<'a, 'tcx, Prov, Extra> {
} }
/// `range` is relative to this allocation reference, not the base of the allocation. /// `range` is relative to this allocation reference, not the base of the allocation.
pub fn read_integer(&self, range: AllocRange) -> InterpResult<'tcx, ScalarMaybeUninit<Prov>> { pub fn read_integer(&self, range: AllocRange) -> InterpResult<'tcx, Scalar<Prov>> {
self.read_scalar(range, /*read_provenance*/ false) self.read_scalar(range, /*read_provenance*/ false)
} }
/// `offset` is relative to this allocation reference, not the base of the allocation. /// `offset` is relative to this allocation reference, not the base of the allocation.
pub fn read_pointer(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit<Prov>> { pub fn read_pointer(&self, offset: Size) -> InterpResult<'tcx, Scalar<Prov>> {
self.read_scalar( self.read_scalar(
alloc_range(offset, self.tcx.data_layout().pointer_size), alloc_range(offset, self.tcx.data_layout().pointer_size),
/*read_provenance*/ true, /*read_provenance*/ true,

View file

@ -1,11 +1,9 @@
//! Functions concerning immediate values and operands, and reading from operands. //! Functions concerning immediate values and operands, and reading from operands.
//! All high-level functions to read from memory work on operands as sources. //! All high-level functions to read from memory work on operands as sources.
use std::fmt::Write;
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
use rustc_middle::ty::{ConstInt, DelaySpanBugEmitted, Ty}; use rustc_middle::ty::{ConstInt, DelaySpanBugEmitted, Ty};
use rustc_middle::{mir, ty}; use rustc_middle::{mir, ty};
use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding}; use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding};
@ -14,7 +12,7 @@ use rustc_target::abi::{VariantIdx, Variants};
use super::{ use super::{
alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, GlobalId, alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, GlobalId,
InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Place, PlaceTy, Pointer, InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Place, PlaceTy, Pointer,
Provenance, Scalar, ScalarMaybeUninit, Provenance, Scalar,
}; };
/// An `Immediate` represents a single immediate self-contained Rust value. /// An `Immediate` represents a single immediate self-contained Rust value.
@ -27,23 +25,14 @@ use super::{
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum Immediate<Prov: Provenance = AllocId> { pub enum Immediate<Prov: Provenance = AllocId> {
/// A single scalar value (must have *initialized* `Scalar` ABI). /// A single scalar value (must have *initialized* `Scalar` ABI).
/// FIXME: we also currently often use this for ZST. Scalar(Scalar<Prov>),
/// `ScalarMaybeUninit` should reject ZST, and we should use `Uninit` for them instead.
Scalar(ScalarMaybeUninit<Prov>),
/// A pair of two scalar value (must have `ScalarPair` ABI where both fields are /// A pair of two scalar value (must have `ScalarPair` ABI where both fields are
/// `Scalar::Initialized`). /// `Scalar::Initialized`).
ScalarPair(ScalarMaybeUninit<Prov>, ScalarMaybeUninit<Prov>), ScalarPair(Scalar<Prov>, Scalar<Prov>),
/// A value of fully uninitialized memory. Can have and size and layout. /// A value of fully uninitialized memory. Can have and size and layout.
Uninit, Uninit,
} }
impl<Prov: Provenance> From<ScalarMaybeUninit<Prov>> for Immediate<Prov> {
#[inline(always)]
fn from(val: ScalarMaybeUninit<Prov>) -> Self {
Immediate::Scalar(val)
}
}
impl<Prov: Provenance> From<Scalar<Prov>> for Immediate<Prov> { impl<Prov: Provenance> From<Scalar<Prov>> for Immediate<Prov> {
#[inline(always)] #[inline(always)]
fn from(val: Scalar<Prov>) -> Self { fn from(val: Scalar<Prov>) -> Self {
@ -51,13 +40,13 @@ impl<Prov: Provenance> From<Scalar<Prov>> for Immediate<Prov> {
} }
} }
impl<'tcx, Prov: Provenance> Immediate<Prov> { impl<Prov: Provenance> Immediate<Prov> {
pub fn from_pointer(p: Pointer<Prov>, cx: &impl HasDataLayout) -> Self { pub fn from_pointer(p: Pointer<Prov>, cx: &impl HasDataLayout) -> Self {
Immediate::Scalar(ScalarMaybeUninit::from_pointer(p, cx)) Immediate::Scalar(Scalar::from_pointer(p, cx))
} }
pub fn from_maybe_pointer(p: Pointer<Option<Prov>>, cx: &impl HasDataLayout) -> Self { pub fn from_maybe_pointer(p: Pointer<Option<Prov>>, cx: &impl HasDataLayout) -> Self {
Immediate::Scalar(ScalarMaybeUninit::from_maybe_pointer(p, cx)) Immediate::Scalar(Scalar::from_maybe_pointer(p, cx))
} }
pub fn new_slice(val: Scalar<Prov>, len: u64, cx: &impl HasDataLayout) -> Self { pub fn new_slice(val: Scalar<Prov>, len: u64, cx: &impl HasDataLayout) -> Self {
@ -69,41 +58,28 @@ impl<'tcx, Prov: Provenance> Immediate<Prov> {
vtable: Pointer<Option<Prov>>, vtable: Pointer<Option<Prov>>,
cx: &impl HasDataLayout, cx: &impl HasDataLayout,
) -> Self { ) -> Self {
Immediate::ScalarPair(val.into(), ScalarMaybeUninit::from_maybe_pointer(vtable, cx)) Immediate::ScalarPair(val.into(), Scalar::from_maybe_pointer(vtable, cx))
} }
#[inline] #[inline]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
pub fn to_scalar_or_uninit(self) -> ScalarMaybeUninit<Prov> { pub fn to_scalar(self) -> Scalar<Prov> {
match self { match self {
Immediate::Scalar(val) => val, Immediate::Scalar(val) => val,
Immediate::ScalarPair(..) => bug!("Got a scalar pair where a scalar was expected"), Immediate::ScalarPair(..) => bug!("Got a scalar pair where a scalar was expected"),
Immediate::Uninit => ScalarMaybeUninit::Uninit, Immediate::Uninit => bug!("Got uninit where a scalar was expected"),
} }
} }
#[inline] #[inline]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
pub fn to_scalar(self) -> InterpResult<'tcx, Scalar<Prov>> { pub fn to_scalar_pair(self) -> (Scalar<Prov>, Scalar<Prov>) {
self.to_scalar_or_uninit().check_init()
}
#[inline]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
pub fn to_scalar_or_uninit_pair(self) -> (ScalarMaybeUninit<Prov>, ScalarMaybeUninit<Prov>) {
match self { match self {
Immediate::ScalarPair(val1, val2) => (val1, val2), Immediate::ScalarPair(val1, val2) => (val1, val2),
Immediate::Scalar(..) => bug!("Got a scalar where a scalar pair was expected"), Immediate::Scalar(..) => bug!("Got a scalar where a scalar pair was expected"),
Immediate::Uninit => (ScalarMaybeUninit::Uninit, ScalarMaybeUninit::Uninit), Immediate::Uninit => bug!("Got uninit where a scalar pair was expected"),
} }
} }
#[inline]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
pub fn to_scalar_pair(self) -> InterpResult<'tcx, (Scalar<Prov>, Scalar<Prov>)> {
let (val1, val2) = self.to_scalar_or_uninit_pair();
Ok((val1.check_init()?, val2.check_init()?))
}
} }
// ScalarPair needs a type to interpret, so we often have an immediate and a type together // ScalarPair needs a type to interpret, so we often have an immediate and a type together
@ -119,27 +95,17 @@ impl<Prov: Provenance> std::fmt::Display for ImmTy<'_, Prov> {
/// Helper function for printing a scalar to a FmtPrinter /// Helper function for printing a scalar to a FmtPrinter
fn p<'a, 'tcx, Prov: Provenance>( fn p<'a, 'tcx, Prov: Provenance>(
cx: FmtPrinter<'a, 'tcx>, cx: FmtPrinter<'a, 'tcx>,
s: ScalarMaybeUninit<Prov>, s: Scalar<Prov>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Result<FmtPrinter<'a, 'tcx>, std::fmt::Error> { ) -> Result<FmtPrinter<'a, 'tcx>, std::fmt::Error> {
match s { match s {
ScalarMaybeUninit::Scalar(Scalar::Int(int)) => { Scalar::Int(int) => cx.pretty_print_const_scalar_int(int, ty, true),
cx.pretty_print_const_scalar_int(int, ty, true) Scalar::Ptr(ptr, _sz) => {
}
ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, _sz)) => {
// Just print the ptr value. `pretty_print_const_scalar_ptr` would also try to // Just print the ptr value. `pretty_print_const_scalar_ptr` would also try to
// print what is points to, which would fail since it has no access to the local // print what is points to, which would fail since it has no access to the local
// memory. // memory.
cx.pretty_print_const_pointer(ptr, ty, true) cx.pretty_print_const_pointer(ptr, ty, true)
} }
ScalarMaybeUninit::Uninit => cx.typed_value(
|mut this| {
this.write_str("uninit ")?;
Ok(this)
},
|this| this.print_type(ty),
" ",
),
} }
} }
ty::tls::with(|tcx| { ty::tls::with(|tcx| {
@ -269,7 +235,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
#[inline] #[inline]
pub fn to_const_int(self) -> ConstInt { pub fn to_const_int(self) -> ConstInt {
assert!(self.layout.ty.is_integral()); assert!(self.layout.ty.is_integral());
let int = self.to_scalar().expect("to_const_int doesn't work on scalar pairs").assert_int(); let int = self.to_scalar().assert_int();
ConstInt::new(int, self.layout.ty.is_signed(), self.layout.ty.is_ptr_sized_integral()) ConstInt::new(int, self.layout.ty.is_signed(), self.layout.ty.is_ptr_sized_integral())
} }
} }
@ -327,7 +293,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
fn read_immediate_from_mplace_raw( fn read_immediate_from_mplace_raw(
&self, &self,
mplace: &MPlaceTy<'tcx, M::Provenance>, mplace: &MPlaceTy<'tcx, M::Provenance>,
force: bool,
) -> InterpResult<'tcx, Option<ImmTy<'tcx, M::Provenance>>> { ) -> InterpResult<'tcx, Option<ImmTy<'tcx, M::Provenance>>> {
if mplace.layout.is_unsized() { if mplace.layout.is_unsized() {
// Don't touch unsized // Don't touch unsized
@ -345,47 +310,44 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// case where some of the bytes are initialized and others are not. So, we need an extra // case where some of the bytes are initialized and others are not. So, we need an extra
// check that walks over the type of `mplace` to make sure it is truly correct to treat this // check that walks over the type of `mplace` to make sure it is truly correct to treat this
// like a `Scalar` (or `ScalarPair`). // like a `Scalar` (or `ScalarPair`).
let scalar_layout = match mplace.layout.abi { Ok(match mplace.layout.abi {
// `if` does not work nested inside patterns, making this a bit awkward to express. Abi::Scalar(abi::Scalar::Initialized { value: s, .. }) => {
Abi::Scalar(abi::Scalar::Initialized { value: s, .. }) => Some(s), let size = s.size(self);
Abi::Scalar(s) if force => Some(s.primitive()), assert_eq!(size, mplace.layout.size, "abi::Scalar size does not match layout size");
_ => None, let scalar = alloc.read_scalar(
}; alloc_range(Size::ZERO, size),
if let Some(s) = scalar_layout { /*read_provenance*/ s.is_ptr(),
let size = s.size(self); )?;
assert_eq!(size, mplace.layout.size, "abi::Scalar size does not match layout size"); Some(ImmTy { imm: scalar.into(), layout: mplace.layout })
let scalar = alloc }
.read_scalar(alloc_range(Size::ZERO, size), /*read_provenance*/ s.is_ptr())?;
return Ok(Some(ImmTy { imm: scalar.into(), layout: mplace.layout }));
}
let scalar_pair_layout = match mplace.layout.abi {
Abi::ScalarPair( Abi::ScalarPair(
abi::Scalar::Initialized { value: a, .. }, abi::Scalar::Initialized { value: a, .. },
abi::Scalar::Initialized { value: b, .. }, abi::Scalar::Initialized { value: b, .. },
) => Some((a, b)), ) => {
Abi::ScalarPair(a, b) if force => Some((a.primitive(), b.primitive())), // We checked `ptr_align` above, so all fields will have the alignment they need.
_ => None, // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`,
}; // which `ptr.offset(b_offset)` cannot possibly fail to satisfy.
if let Some((a, b)) = scalar_pair_layout { let (a_size, b_size) = (a.size(self), b.size(self));
// We checked `ptr_align` above, so all fields will have the alignment they need. let b_offset = a_size.align_to(b.align(self).abi);
// We would anyway check against `ptr_align.restrict_for_offset(b_offset)`, assert!(b_offset.bytes() > 0); // in `operand_field` we use the offset to tell apart the fields
// which `ptr.offset(b_offset)` cannot possibly fail to satisfy. let a_val = alloc.read_scalar(
let (a_size, b_size) = (a.size(self), b.size(self)); alloc_range(Size::ZERO, a_size),
let b_offset = a_size.align_to(b.align(self).abi); /*read_provenance*/ a.is_ptr(),
assert!(b_offset.bytes() > 0); // in `operand_field` we use the offset to tell apart the fields )?;
let a_val = alloc.read_scalar( let b_val = alloc.read_scalar(
alloc_range(Size::ZERO, a_size), alloc_range(b_offset, b_size),
/*read_provenance*/ a.is_ptr(), /*read_provenance*/ b.is_ptr(),
)?; )?;
let b_val = alloc Some(ImmTy {
.read_scalar(alloc_range(b_offset, b_size), /*read_provenance*/ b.is_ptr())?; imm: Immediate::ScalarPair(a_val.into(), b_val.into()),
return Ok(Some(ImmTy { layout: mplace.layout,
imm: Immediate::ScalarPair(a_val, b_val), })
layout: mplace.layout, }
})); _ => {
} // Neither a scalar nor scalar pair.
// Neither a scalar nor scalar pair. None
return Ok(None); }
})
} }
/// Try returning an immediate for the operand. If the layout does not permit loading this as an /// Try returning an immediate for the operand. If the layout does not permit loading this as an
@ -394,20 +356,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// succeed! Whether it succeeds depends on whether the layout can be represented /// succeed! Whether it succeeds depends on whether the layout can be represented
/// in an `Immediate`, not on which data is stored there currently. /// in an `Immediate`, not on which data is stored there currently.
/// ///
/// If `force` is `true`, then even scalars with fields that can be ununit will be
/// read. This means the load is lossy and should not be written back!
/// This flag exists only for validity checking.
///
/// This is an internal function that should not usually be used; call `read_immediate` instead. /// This is an internal function that should not usually be used; call `read_immediate` instead.
/// ConstProp needs it, though. /// ConstProp needs it, though.
pub fn read_immediate_raw( pub fn read_immediate_raw(
&self, &self,
src: &OpTy<'tcx, M::Provenance>, src: &OpTy<'tcx, M::Provenance>,
force: bool,
) -> InterpResult<'tcx, Result<ImmTy<'tcx, M::Provenance>, MPlaceTy<'tcx, M::Provenance>>> { ) -> InterpResult<'tcx, Result<ImmTy<'tcx, M::Provenance>, MPlaceTy<'tcx, M::Provenance>>> {
Ok(match src.try_as_mplace() { Ok(match src.try_as_mplace() {
Ok(ref mplace) => { Ok(ref mplace) => {
if let Some(val) = self.read_immediate_from_mplace_raw(mplace, force)? { if let Some(val) = self.read_immediate_from_mplace_raw(mplace)? {
Ok(val) Ok(val)
} else { } else {
Err(*mplace) Err(*mplace)
@ -418,24 +375,33 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
/// Read an immediate from a place, asserting that that is possible with the given layout. /// Read an immediate from a place, asserting that that is possible with the given layout.
///
/// If this suceeds, the `ImmTy` is never `Uninit`.
#[inline(always)] #[inline(always)]
pub fn read_immediate( pub fn read_immediate(
&self, &self,
op: &OpTy<'tcx, M::Provenance>, op: &OpTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> { ) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
if let Ok(imm) = self.read_immediate_raw(op, /*force*/ false)? { if !matches!(
Ok(imm) op.layout.abi,
} else { Abi::Scalar(abi::Scalar::Initialized { .. })
span_bug!(self.cur_span(), "primitive read failed for type: {:?}", op.layout.ty); | Abi::ScalarPair(abi::Scalar::Initialized { .. }, abi::Scalar::Initialized { .. })
) {
span_bug!(self.cur_span(), "primitive read not possible for type: {:?}", op.layout.ty);
} }
let imm = self.read_immediate_raw(op)?.unwrap();
if matches!(*imm, Immediate::Uninit) {
throw_ub!(InvalidUninitBytes(None));
}
Ok(imm)
} }
/// Read a scalar from a place /// Read a scalar from a place
pub fn read_scalar( pub fn read_scalar(
&self, &self,
op: &OpTy<'tcx, M::Provenance>, op: &OpTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, ScalarMaybeUninit<M::Provenance>> { ) -> InterpResult<'tcx, Scalar<M::Provenance>> {
Ok(self.read_immediate(op)?.to_scalar_or_uninit()) Ok(self.read_immediate(op)?.to_scalar())
} }
/// Read a pointer from a place. /// Read a pointer from a place.
@ -727,7 +693,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Figure out which discriminant and variant this corresponds to. // Figure out which discriminant and variant this corresponds to.
Ok(match *tag_encoding { Ok(match *tag_encoding {
TagEncoding::Direct => { TagEncoding::Direct => {
let scalar = tag_val.to_scalar()?; let scalar = tag_val.to_scalar();
// Generate a specific error if `tag_val` is not an integer. // Generate a specific error if `tag_val` is not an integer.
// (`tag_bits` itself is only used for error messages below.) // (`tag_bits` itself is only used for error messages below.)
let tag_bits = scalar let tag_bits = scalar
@ -758,7 +724,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
(discr_val, index.0) (discr_val, index.0)
} }
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => { TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
let tag_val = tag_val.to_scalar()?; let tag_val = tag_val.to_scalar();
// Compute the variant this niche value/"tag" corresponds to. With niche layout, // Compute the variant this niche value/"tag" corresponds to. With niche layout,
// discriminant (encoded in niche/tag) and variant index are the same. // discriminant (encoded in niche/tag) and variant index are the same.
let variants_start = niche_variants.start().as_u32(); let variants_start = niche_variants.start().as_u32();
@ -785,9 +751,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let niche_start_val = ImmTy::from_uint(niche_start, tag_layout); let niche_start_val = ImmTy::from_uint(niche_start, tag_layout);
let variant_index_relative_val = let variant_index_relative_val =
self.binary_op(mir::BinOp::Sub, &tag_val, &niche_start_val)?; self.binary_op(mir::BinOp::Sub, &tag_val, &niche_start_val)?;
let variant_index_relative = variant_index_relative_val let variant_index_relative =
.to_scalar()? variant_index_relative_val.to_scalar().assert_bits(tag_val.layout.size);
.assert_bits(tag_val.layout.size);
// Check if this is in the range that indicates an actual discriminant. // 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_end - variants_start) {
let variant_index_relative = u32::try_from(variant_index_relative) let variant_index_relative = u32::try_from(variant_index_relative)

View file

@ -329,21 +329,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match left.layout.ty.kind() { match left.layout.ty.kind() {
ty::Char => { ty::Char => {
assert_eq!(left.layout.ty, right.layout.ty); assert_eq!(left.layout.ty, right.layout.ty);
let left = left.to_scalar()?; let left = left.to_scalar();
let right = right.to_scalar()?; let right = right.to_scalar();
Ok(self.binary_char_op(bin_op, left.to_char()?, right.to_char()?)) Ok(self.binary_char_op(bin_op, left.to_char()?, right.to_char()?))
} }
ty::Bool => { ty::Bool => {
assert_eq!(left.layout.ty, right.layout.ty); assert_eq!(left.layout.ty, right.layout.ty);
let left = left.to_scalar()?; let left = left.to_scalar();
let right = right.to_scalar()?; let right = right.to_scalar();
Ok(self.binary_bool_op(bin_op, left.to_bool()?, right.to_bool()?)) Ok(self.binary_bool_op(bin_op, left.to_bool()?, right.to_bool()?))
} }
ty::Float(fty) => { ty::Float(fty) => {
assert_eq!(left.layout.ty, right.layout.ty); assert_eq!(left.layout.ty, right.layout.ty);
let ty = left.layout.ty; let ty = left.layout.ty;
let left = left.to_scalar()?; let left = left.to_scalar();
let right = right.to_scalar()?; let right = right.to_scalar();
Ok(match fty { Ok(match fty {
FloatTy::F32 => { FloatTy::F32 => {
self.binary_float_op(bin_op, ty, left.to_f32()?, right.to_f32()?) self.binary_float_op(bin_op, ty, left.to_f32()?, right.to_f32()?)
@ -363,8 +363,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
right.layout.ty right.layout.ty
); );
let l = left.to_scalar()?.to_bits(left.layout.size)?; let l = left.to_scalar().to_bits(left.layout.size)?;
let r = right.to_scalar()?.to_bits(right.layout.size)?; let r = right.to_scalar().to_bits(right.layout.size)?;
self.binary_int_op(bin_op, l, left.layout, r, right.layout) self.binary_int_op(bin_op, l, left.layout, r, right.layout)
} }
_ if left.layout.ty.is_any_ptr() => { _ if left.layout.ty.is_any_ptr() => {
@ -410,7 +410,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
use rustc_middle::mir::UnOp::*; use rustc_middle::mir::UnOp::*;
let layout = val.layout; let layout = val.layout;
let val = val.to_scalar()?; let val = val.to_scalar();
trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty); trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty);
match layout.ty.kind() { match layout.ty.kind() {

View file

@ -13,7 +13,7 @@ use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding, Vari
use super::{ use super::{
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg,
ConstAlloc, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, OpTy, Operand, ConstAlloc, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, OpTy, Operand,
Pointer, Provenance, Scalar, ScalarMaybeUninit, Pointer, Provenance, Scalar,
}; };
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
@ -254,8 +254,6 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> {
// These are defined here because they produce a place. // These are defined here because they produce a place.
impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
#[inline(always)] #[inline(always)]
/// Note: do not call `as_ref` on the resulting place. This function should only be used to
/// read from the resulting mplace, not to get its address back.
pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> { pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> {
match **self { match **self {
Operand::Indirect(mplace) => { Operand::Indirect(mplace) => {
@ -267,8 +265,6 @@ impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
#[inline(always)] #[inline(always)]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
/// Note: do not call `as_ref` on the resulting place. This function should only be used to
/// read from the resulting mplace, not to get its address back.
pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> { pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> {
self.try_as_mplace().unwrap() self.try_as_mplace().unwrap()
} }
@ -312,7 +308,7 @@ where
let layout = self.layout_of(pointee_type)?; let layout = self.layout_of(pointee_type)?;
let (ptr, meta) = match **val { let (ptr, meta) = match **val {
Immediate::Scalar(ptr) => (ptr, MemPlaceMeta::None), Immediate::Scalar(ptr) => (ptr, MemPlaceMeta::None),
Immediate::ScalarPair(ptr, meta) => (ptr, MemPlaceMeta::Meta(meta.check_init()?)), Immediate::ScalarPair(ptr, meta) => (ptr, MemPlaceMeta::Meta(meta)),
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)), Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
}; };
@ -467,7 +463,7 @@ where
#[inline(always)] #[inline(always)]
pub fn write_scalar( pub fn write_scalar(
&mut self, &mut self,
val: impl Into<ScalarMaybeUninit<M::Provenance>>, val: impl Into<Scalar<M::Provenance>>,
dest: &PlaceTy<'tcx, M::Provenance>, dest: &PlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
self.write_immediate(Immediate::Scalar(val.into()), dest) self.write_immediate(Immediate::Scalar(val.into()), dest)
@ -644,7 +640,7 @@ where
// Let us see if the layout is simple so we take a shortcut, // Let us see if the layout is simple so we take a shortcut,
// avoid force_allocation. // avoid force_allocation.
let src = match self.read_immediate_raw(src, /*force*/ false)? { let src = match self.read_immediate_raw(src)? {
Ok(src_val) => { Ok(src_val) => {
assert!(!src.layout.is_unsized(), "cannot have unsized immediates"); assert!(!src.layout.is_unsized(), "cannot have unsized immediates");
assert!( assert!(

View file

@ -129,8 +129,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
Assert { ref cond, expected, ref msg, target, cleanup } => { Assert { ref cond, expected, ref msg, target, cleanup } => {
let cond_val = let cond_val = self.read_scalar(&self.eval_operand(cond, None)?)?.to_bool()?;
self.read_immediate(&self.eval_operand(cond, None)?)?.to_scalar()?.to_bool()?;
if expected == cond_val { if expected == cond_val {
self.go_to_block(target); self.go_to_block(target);
} else { } else {

View file

@ -20,8 +20,8 @@ use rustc_target::abi::{Abi, Scalar as ScalarAbi, Size, VariantIdx, Variants, Wr
use std::hash::Hash; use std::hash::Hash;
use super::{ use super::{
alloc_range, CheckInAllocMsg, GlobalAlloc, Immediate, InterpCx, InterpResult, MPlaceTy, alloc_range, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy,
Machine, MemPlaceMeta, OpTy, Scalar, ScalarMaybeUninit, ValueVisitor, Machine, MemPlaceMeta, OpTy, Scalar, ValueVisitor,
}; };
macro_rules! throw_validation_failure { macro_rules! throw_validation_failure {
@ -304,6 +304,27 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
Ok(r) Ok(r)
} }
fn read_immediate(
&self,
op: &OpTy<'tcx, M::Provenance>,
expected: &str,
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
Ok(try_validation!(
self.ecx.read_immediate(op),
self.path,
err_unsup!(ReadPointerAsBytes) => { "(potentially part of) a pointer" } expected { "{expected}" },
err_ub!(InvalidUninitBytes(None)) => { "uninitialized memory" } expected { "{expected}" }
))
}
fn read_scalar(
&self,
op: &OpTy<'tcx, M::Provenance>,
expected: &str,
) -> InterpResult<'tcx, Scalar<M::Provenance>> {
Ok(self.read_immediate(op, expected)?.to_scalar())
}
fn check_wide_ptr_meta( fn check_wide_ptr_meta(
&mut self, &mut self,
meta: MemPlaceMeta<M::Provenance>, meta: MemPlaceMeta<M::Provenance>,
@ -348,18 +369,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
value: &OpTy<'tcx, M::Provenance>, value: &OpTy<'tcx, M::Provenance>,
kind: &str, kind: &str,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
let value = try_validation!( let place = self.ecx.ref_to_mplace(&self.read_immediate(value, &format!("a {kind}"))?)?;
self.ecx.read_immediate(value),
self.path,
err_unsup!(ReadPointerAsBytes) => { "part of a pointer" } expected { "a proper pointer or integer value" },
);
// Handle wide pointers. // Handle wide pointers.
// Check metadata early, for better diagnostics // Check metadata early, for better diagnostics
let place = try_validation!(
self.ecx.ref_to_mplace(&value),
self.path,
err_ub!(InvalidUninitBytes(None)) => { "uninitialized {}", kind },
);
if place.layout.is_unsized() { if place.layout.is_unsized() {
self.check_wide_ptr_meta(place.meta, place.layout)?; self.check_wide_ptr_meta(place.meta, place.layout)?;
} }
@ -454,28 +466,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
Ok(()) Ok(())
} }
fn read_scalar(
&self,
op: &OpTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, ScalarMaybeUninit<M::Provenance>> {
Ok(try_validation!(
self.ecx.read_scalar(op),
self.path,
err_unsup!(ReadPointerAsBytes) => { "(potentially part of) a pointer" } expected { "plain (non-pointer) bytes" },
))
}
fn read_immediate_forced(
&self,
op: &OpTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, Immediate<M::Provenance>> {
Ok(*try_validation!(
self.ecx.read_immediate_raw(op, /*force*/ true),
self.path,
err_unsup!(ReadPointerAsBytes) => { "(potentially part of) a pointer" } expected { "plain (non-pointer) bytes" },
).unwrap())
}
/// Check if this is a value of primitive type, and if yes check the validity of the value /// Check if this is a value of primitive type, and if yes check the validity of the value
/// at that type. Return `true` if the type is indeed primitive. /// at that type. Return `true` if the type is indeed primitive.
fn try_visit_primitive( fn try_visit_primitive(
@ -486,39 +476,39 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
let ty = value.layout.ty; let ty = value.layout.ty;
match ty.kind() { match ty.kind() {
ty::Bool => { ty::Bool => {
let value = self.read_scalar(value)?; let value = self.read_scalar(value, "a boolean")?;
try_validation!( try_validation!(
value.to_bool(), value.to_bool(),
self.path, self.path,
err_ub!(InvalidBool(..)) | err_ub!(InvalidUninitBytes(None)) => err_ub!(InvalidBool(..)) =>
{ "{:x}", value } expected { "a boolean" }, { "{:x}", value } expected { "a boolean" },
); );
Ok(true) Ok(true)
} }
ty::Char => { ty::Char => {
let value = self.read_scalar(value)?; let value = self.read_scalar(value, "a unicode scalar value")?;
try_validation!( try_validation!(
value.to_char(), value.to_char(),
self.path, self.path,
err_ub!(InvalidChar(..)) | err_ub!(InvalidUninitBytes(None)) => err_ub!(InvalidChar(..)) =>
{ "{:x}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" }, { "{:x}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
); );
Ok(true) Ok(true)
} }
ty::Float(_) | ty::Int(_) | ty::Uint(_) => { ty::Float(_) | ty::Int(_) | ty::Uint(_) => {
let value = self.read_scalar(value)?;
// NOTE: Keep this in sync with the array optimization for int/float // NOTE: Keep this in sync with the array optimization for int/float
// types below! // types below!
try_validation!( let value = self.read_scalar(
value.check_init(), value,
self.path, if matches!(ty.kind(), ty::Float(..)) {
err_ub!(InvalidUninitBytes(..)) => "a floating point number"
{ "{:x}", value } expected { "initialized bytes" } } else {
); "an integer"
},
)?;
// As a special exception we *do* match on a `Scalar` here, since we truly want // As a special exception we *do* match on a `Scalar` here, since we truly want
// to know its underlying representation (and *not* cast it to an integer). // to know its underlying representation (and *not* cast it to an integer).
let is_ptr = value.check_init().map_or(false, |v| matches!(v, Scalar::Ptr(..))); if matches!(value, Scalar::Ptr(..)) {
if is_ptr {
throw_validation_failure!(self.path, throw_validation_failure!(self.path,
{ "{:x}", value } expected { "plain (non-pointer) bytes" } { "{:x}", value } expected { "plain (non-pointer) bytes" }
) )
@ -529,12 +519,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
// We are conservative with uninit for integers, but try to // We are conservative with uninit for integers, but try to
// actually enforce the strict rules for raw pointers (mostly because // actually enforce the strict rules for raw pointers (mostly because
// that lets us re-use `ref_to_mplace`). // that lets us re-use `ref_to_mplace`).
let place = try_validation!( let place =
self.ecx.read_immediate(value).and_then(|ref i| self.ecx.ref_to_mplace(i)), self.ecx.ref_to_mplace(&self.read_immediate(value, "a raw pointer")?)?;
self.path,
err_ub!(InvalidUninitBytes(None)) => { "uninitialized raw pointer" },
err_unsup!(ReadPointerAsBytes) => { "part of a pointer" } expected { "a proper pointer or integer value" },
);
if place.layout.is_unsized() { if place.layout.is_unsized() {
self.check_wide_ptr_meta(place.meta, place.layout)?; self.check_wide_ptr_meta(place.meta, place.layout)?;
} }
@ -555,12 +541,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
Ok(true) Ok(true)
} }
ty::FnPtr(_sig) => { ty::FnPtr(_sig) => {
let value = try_validation!( let value = self.read_scalar(value, "a function pointer")?;
self.ecx.read_scalar(value).and_then(|v| v.check_init()),
self.path,
err_unsup!(ReadPointerAsBytes) => { "part of a pointer" } expected { "a proper pointer or integer value" },
err_ub!(InvalidUninitBytes(None)) => { "uninitialized bytes" } expected { "a proper pointer or integer value" },
);
// If we check references recursively, also check that this points to a function. // If we check references recursively, also check that this points to a function.
if let Some(_) = self.ref_tracking { if let Some(_) = self.ref_tracking {
@ -611,34 +592,15 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
fn visit_scalar( fn visit_scalar(
&mut self, &mut self,
scalar: ScalarMaybeUninit<M::Provenance>, scalar: Scalar<M::Provenance>,
scalar_layout: ScalarAbi, scalar_layout: ScalarAbi,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// We check `is_full_range` in a slightly complicated way because *if* we are checking
// number validity, then we want to ensure that `Scalar::Initialized` is indeed initialized,
// i.e. that we go over the `check_init` below.
let size = scalar_layout.size(self.ecx); let size = scalar_layout.size(self.ecx);
let is_full_range = match scalar_layout {
ScalarAbi::Initialized { .. } => false, // not "full" since uninit is not valid
ScalarAbi::Union { .. } => true,
};
if is_full_range {
// Nothing to check. Cruciall we don't even `read_scalar` until here, since that would
// fail for `Union` scalars!
return Ok(());
}
// We have something to check: it must at least be initialized.
let valid_range = scalar_layout.valid_range(self.ecx); let valid_range = scalar_layout.valid_range(self.ecx);
let WrappingRange { start, end } = valid_range; let WrappingRange { start, end } = valid_range;
let max_value = size.unsigned_int_max(); let max_value = size.unsigned_int_max();
assert!(end <= max_value); assert!(end <= max_value);
let value = try_validation!( let bits = match scalar.try_to_int() {
scalar.check_init(),
self.path,
err_ub!(InvalidUninitBytes(None)) => { "{:x}", scalar }
expected { "something {}", wrapping_range_format(valid_range, max_value) },
);
let bits = match value.try_to_int() {
Ok(int) => int.assert_bits(size), Ok(int) => int.assert_bits(size),
Err(_) => { Err(_) => {
// So this is a pointer then, and casting to an int failed. // So this is a pointer then, and casting to an int failed.
@ -646,7 +608,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
// We support 2 kinds of ranges here: full range, and excluding zero. // We support 2 kinds of ranges here: full range, and excluding zero.
if start == 1 && end == max_value { if start == 1 && end == max_value {
// Only null is the niche. So make sure the ptr is NOT null. // Only null is the niche. So make sure the ptr is NOT null.
if self.ecx.scalar_may_be_null(value)? { if self.ecx.scalar_may_be_null(scalar)? {
throw_validation_failure!(self.path, throw_validation_failure!(self.path,
{ "a potentially null pointer" } { "a potentially null pointer" }
expected { expected {
@ -800,10 +762,11 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
); );
} }
Abi::Scalar(scalar_layout) => { Abi::Scalar(scalar_layout) => {
// We use a 'forced' read because we always need a `Immediate` here if !scalar_layout.is_uninit_valid() {
// and treating "partially uninit" as "fully uninit" is fine for us. // There is something to check here.
let scalar = self.read_immediate_forced(op)?.to_scalar_or_uninit(); let scalar = self.read_scalar(op, "initiailized scalar value")?;
self.visit_scalar(scalar, scalar_layout)?; self.visit_scalar(scalar, scalar_layout)?;
}
} }
Abi::ScalarPair(a_layout, b_layout) => { Abi::ScalarPair(a_layout, b_layout) => {
// There is no `rustc_layout_scalar_valid_range_start` for pairs, so // There is no `rustc_layout_scalar_valid_range_start` for pairs, so
@ -811,10 +774,15 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// but that can miss bugs in layout computation. Layout computation // but that can miss bugs in layout computation. Layout computation
// is subtle due to enums having ScalarPair layout, where one field // is subtle due to enums having ScalarPair layout, where one field
// is the discriminant. // is the discriminant.
if cfg!(debug_assertions) { if cfg!(debug_assertions)
// We use a 'forced' read because we always need a `Immediate` here && !a_layout.is_uninit_valid()
// and treating "partially uninit" as "fully uninit" is fine for us. && !b_layout.is_uninit_valid()
let (a, b) = self.read_immediate_forced(op)?.to_scalar_or_uninit_pair(); {
// We can only proceed if *both* scalars need to be initialized.
// FIXME: find a way to also check ScalarPair when one side can be uninit but
// the other must be init.
let (a, b) =
self.read_immediate(op, "initiailized scalar value")?.to_scalar_pair();
self.visit_scalar(a, a_layout)?; self.visit_scalar(a, a_layout)?;
self.visit_scalar(b, b_layout)?; self.visit_scalar(b, b_layout)?;
} }

View file

@ -16,8 +16,8 @@ use rustc_target::abi::{Align, HasDataLayout, Size};
use super::{ use super::{
read_target_uint, write_target_uint, AllocId, InterpError, InterpResult, Pointer, Provenance, read_target_uint, write_target_uint, AllocId, InterpError, InterpResult, Pointer, Provenance,
ResourceExhaustionInfo, Scalar, ScalarMaybeUninit, ScalarSizeMismatch, UndefinedBehaviorInfo, ResourceExhaustionInfo, Scalar, ScalarSizeMismatch, UndefinedBehaviorInfo, UninitBytesAccess,
UninitBytesAccess, UnsupportedOpInfo, UnsupportedOpInfo,
}; };
use crate::ty; use crate::ty;
@ -437,16 +437,14 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
cx: &impl HasDataLayout, cx: &impl HasDataLayout,
range: AllocRange, range: AllocRange,
read_provenance: bool, read_provenance: bool,
) -> AllocResult<ScalarMaybeUninit<Prov>> { ) -> AllocResult<Scalar<Prov>> {
if read_provenance { if read_provenance {
assert_eq!(range.size, cx.data_layout().pointer_size); assert_eq!(range.size, cx.data_layout().pointer_size);
} }
// First and foremost, if anything is uninit, bail. // First and foremost, if anything is uninit, bail.
if self.is_init(range).is_err() { if self.is_init(range).is_err() {
// This inflates uninitialized bytes to the entire scalar, even if only a few return Err(AllocError::InvalidUninitBytes(None));
// bytes are uninitialized.
return Ok(ScalarMaybeUninit::Uninit);
} }
// If we are doing a pointer read, and there is a relocation exactly where we // If we are doing a pointer read, and there is a relocation exactly where we
@ -456,7 +454,7 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
let bytes = self.get_bytes_even_more_internal(range); let bytes = self.get_bytes_even_more_internal(range);
let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap(); let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
let ptr = Pointer::new(prov, Size::from_bytes(bits)); let ptr = Pointer::new(prov, Size::from_bytes(bits));
return Ok(ScalarMaybeUninit::from_pointer(ptr, cx)); return Ok(Scalar::from_pointer(ptr, cx));
} }
// If we are *not* reading a pointer, and we can just ignore relocations, // If we are *not* reading a pointer, and we can just ignore relocations,
@ -465,7 +463,7 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
// We just strip provenance. // We just strip provenance.
let bytes = self.get_bytes_even_more_internal(range); let bytes = self.get_bytes_even_more_internal(range);
let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap(); let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
return Ok(ScalarMaybeUninit::Scalar(Scalar::from_uint(bits, range.size))); return Ok(Scalar::from_uint(bits, range.size));
} }
// It's complicated. Better make sure there is no provenance anywhere. // It's complicated. Better make sure there is no provenance anywhere.
@ -477,7 +475,7 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
// underlying bits. // underlying bits.
let bytes = self.get_bytes(cx, range)?; let bytes = self.get_bytes(cx, range)?;
let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap(); let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
Ok(ScalarMaybeUninit::Scalar(Scalar::from_uint(bits, range.size))) Ok(Scalar::from_uint(bits, range.size))
} }
/// Writes a *non-ZST* scalar. /// Writes a *non-ZST* scalar.
@ -492,17 +490,10 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
&mut self, &mut self,
cx: &impl HasDataLayout, cx: &impl HasDataLayout,
range: AllocRange, range: AllocRange,
val: ScalarMaybeUninit<Prov>, val: Scalar<Prov>,
) -> AllocResult { ) -> AllocResult {
assert!(self.mutability == Mutability::Mut); assert!(self.mutability == Mutability::Mut);
let val = match val {
ScalarMaybeUninit::Scalar(scalar) => scalar,
ScalarMaybeUninit::Uninit => {
return self.write_uninit(cx, range);
}
};
// `to_bits_or_ptr_internal` is the right method because we just want to store this data // `to_bits_or_ptr_internal` is the right method because we just want to store this data
// as-is into memory. // as-is into memory.
let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? { let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? {

View file

@ -1,7 +1,7 @@
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fmt; use std::fmt;
use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar, ScalarMaybeUninit}; use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar};
use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt}; use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt};
use rustc_ast::Mutability; use rustc_ast::Mutability;
@ -87,7 +87,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
let instance = ty::Instance::resolve_drop_in_place(tcx, ty); let instance = ty::Instance::resolve_drop_in_place(tcx, ty);
let fn_alloc_id = tcx.create_fn_alloc(instance); let fn_alloc_id = tcx.create_fn_alloc(instance);
let fn_ptr = Pointer::from(fn_alloc_id); let fn_ptr = Pointer::from(fn_alloc_id);
ScalarMaybeUninit::from_pointer(fn_ptr, &tcx) Scalar::from_pointer(fn_ptr, &tcx)
} }
VtblEntry::MetadataSize => Scalar::from_uint(size, ptr_size).into(), VtblEntry::MetadataSize => Scalar::from_uint(size, ptr_size).into(),
VtblEntry::MetadataAlign => Scalar::from_uint(align, ptr_size).into(), VtblEntry::MetadataAlign => Scalar::from_uint(align, ptr_size).into(),
@ -97,14 +97,14 @@ pub(super) fn vtable_allocation_provider<'tcx>(
let instance = instance.polymorphize(tcx); let instance = instance.polymorphize(tcx);
let fn_alloc_id = tcx.create_fn_alloc(instance); let fn_alloc_id = tcx.create_fn_alloc(instance);
let fn_ptr = Pointer::from(fn_alloc_id); let fn_ptr = Pointer::from(fn_alloc_id);
ScalarMaybeUninit::from_pointer(fn_ptr, &tcx) Scalar::from_pointer(fn_ptr, &tcx)
} }
VtblEntry::TraitVPtr(trait_ref) => { VtblEntry::TraitVPtr(trait_ref) => {
let super_trait_ref = trait_ref let super_trait_ref = trait_ref
.map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref));
let supertrait_alloc_id = tcx.vtable_allocation((ty, Some(super_trait_ref))); let supertrait_alloc_id = tcx.vtable_allocation((ty, Some(super_trait_ref)));
let vptr = Pointer::from(supertrait_alloc_id); let vptr = Pointer::from(supertrait_alloc_id);
ScalarMaybeUninit::from_pointer(vptr, &tcx) Scalar::from_pointer(vptr, &tcx)
} }
}; };
vtable vtable

View file

@ -28,7 +28,7 @@ use crate::MirPass;
use rustc_const_eval::interpret::{ use rustc_const_eval::interpret::{
self, compile_time_machine, AllocId, ConstAllocation, ConstValue, CtfeValidationMode, Frame, self, compile_time_machine, AllocId, ConstAllocation, ConstValue, CtfeValidationMode, Frame,
ImmTy, Immediate, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, PlaceTy, ImmTy, Immediate, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, PlaceTy,
Pointer, Scalar, ScalarMaybeUninit, StackPopCleanup, StackPopUnwind, Pointer, Scalar, StackPopCleanup, StackPopUnwind,
}; };
/// The maximum number of bytes that we'll allocate space for a local or the return value. /// The maximum number of bytes that we'll allocate space for a local or the return value.
@ -440,7 +440,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// Try to read the local as an immediate so that if it is representable as a scalar, we can // Try to read the local as an immediate so that if it is representable as a scalar, we can
// handle it as such, but otherwise, just return the value as is. // handle it as such, but otherwise, just return the value as is.
Some(match self.ecx.read_immediate_raw(&op, /*force*/ false) { Some(match self.ecx.read_immediate_raw(&op) {
Ok(Ok(imm)) => imm.into(), Ok(Ok(imm)) => imm.into(),
_ => op, _ => op,
}) })
@ -532,8 +532,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
let left_ty = left.ty(self.local_decls, self.tcx); let left_ty = left.ty(self.local_decls, self.tcx);
let left_size = self.ecx.layout_of(left_ty).ok()?.size; let left_size = self.ecx.layout_of(left_ty).ok()?.size;
let right_size = r.layout.size; let right_size = r.layout.size;
let r_bits = r.to_scalar().ok(); let r_bits = r.to_scalar().to_bits(right_size).ok();
let r_bits = r_bits.and_then(|r| r.to_bits(right_size).ok());
if r_bits.map_or(false, |b| b >= left_size.bits() as u128) { if r_bits.map_or(false, |b| b >= left_size.bits() as u128) {
return None; return None;
} }
@ -562,7 +561,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// and use it to do const-prop here and everywhere else // and use it to do const-prop here and everywhere else
// where it makes sense. // where it makes sense.
if let interpret::Operand::Immediate(interpret::Immediate::Scalar( if let interpret::Operand::Immediate(interpret::Immediate::Scalar(
ScalarMaybeUninit::Scalar(scalar), scalar,
)) = *value )) = *value
{ {
*operand = self.operand_from_scalar( *operand = self.operand_from_scalar(
@ -675,7 +674,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
return this.ecx.eval_rvalue_into_place(rvalue, place); return this.ecx.eval_rvalue_into_place(rvalue, place);
} }
let arg_value = const_arg.to_scalar()?.to_bits(const_arg.layout.size)?; let arg_value = const_arg.to_scalar().to_bits(const_arg.layout.size)?;
let dest = this.ecx.eval_place(place)?; let dest = this.ecx.eval_place(place)?;
match op { match op {
@ -689,7 +688,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
BinOp::Mul if const_arg.layout.ty.is_integral() && arg_value == 0 => { BinOp::Mul if const_arg.layout.ty.is_integral() && arg_value == 0 => {
if let Rvalue::CheckedBinaryOp(_, _) = rvalue { if let Rvalue::CheckedBinaryOp(_, _) = rvalue {
let val = Immediate::ScalarPair( let val = Immediate::ScalarPair(
const_arg.to_scalar()?.into(), const_arg.to_scalar().into(),
Scalar::from_bool(false).into(), Scalar::from_bool(false).into(),
); );
this.ecx.write_immediate(val, &dest) this.ecx.write_immediate(val, &dest)
@ -743,21 +742,18 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
} }
// FIXME> figure out what to do when read_immediate_raw fails // FIXME> figure out what to do when read_immediate_raw fails
let imm = self.use_ecx(|this| this.ecx.read_immediate_raw(value, /*force*/ false)); let imm = self.use_ecx(|this| this.ecx.read_immediate_raw(value));
if let Some(Ok(imm)) = imm { if let Some(Ok(imm)) = imm {
match *imm { match *imm {
interpret::Immediate::Scalar(ScalarMaybeUninit::Scalar(scalar)) => { interpret::Immediate::Scalar(scalar) => {
*rval = Rvalue::Use(self.operand_from_scalar( *rval = Rvalue::Use(self.operand_from_scalar(
scalar, scalar,
value.layout.ty, value.layout.ty,
source_info.span, source_info.span,
)); ));
} }
Immediate::ScalarPair( Immediate::ScalarPair(..) => {
ScalarMaybeUninit::Scalar(_),
ScalarMaybeUninit::Scalar(_),
) => {
// Found a value represented as a pair. For now only do const-prop if the type // Found a value represented as a pair. For now only do const-prop if the type
// of `rvalue` is also a tuple with two scalars. // of `rvalue` is also a tuple with two scalars.
// FIXME: enable the general case stated above ^. // FIXME: enable the general case stated above ^.
@ -812,13 +808,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
} }
match **op { match **op {
interpret::Operand::Immediate(Immediate::Scalar(ScalarMaybeUninit::Scalar(s))) => { interpret::Operand::Immediate(Immediate::Scalar(s)) => s.try_to_int().is_ok(),
s.try_to_int().is_ok() interpret::Operand::Immediate(Immediate::ScalarPair(l, r)) => {
l.try_to_int().is_ok() && r.try_to_int().is_ok()
} }
interpret::Operand::Immediate(Immediate::ScalarPair(
ScalarMaybeUninit::Scalar(l),
ScalarMaybeUninit::Scalar(r),
)) => l.try_to_int().is_ok() && r.try_to_int().is_ok(),
_ => false, _ => false,
} }
} }
@ -1079,7 +1072,7 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
TerminatorKind::Assert { expected, ref mut cond, .. } => { TerminatorKind::Assert { expected, ref mut cond, .. } => {
if let Some(ref value) = self.eval_operand(&cond) { if let Some(ref value) = self.eval_operand(&cond) {
trace!("assertion on {:?} should be {:?}", value, expected); trace!("assertion on {:?} should be {:?}", value, expected);
let expected = ScalarMaybeUninit::from(Scalar::from_bool(*expected)); let expected = Scalar::from_bool(*expected);
let value_const = self.ecx.read_scalar(&value).unwrap(); let value_const = self.ecx.read_scalar(&value).unwrap();
if expected != value_const { if expected != value_const {
// Poison all places this operand references so that further code // Poison all places this operand references so that further code
@ -1092,13 +1085,11 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
} }
} else { } else {
if self.should_const_prop(value) { if self.should_const_prop(value) {
if let ScalarMaybeUninit::Scalar(scalar) = value_const { *cond = self.operand_from_scalar(
*cond = self.operand_from_scalar( value_const,
scalar, self.tcx.types.bool,
self.tcx.types.bool, source_info.span,
source_info.span, );
);
}
} }
} }
} }

View file

@ -7,8 +7,7 @@ use crate::const_prop::ConstPropMode;
use crate::MirLint; use crate::MirLint;
use rustc_const_eval::const_eval::ConstEvalErr; use rustc_const_eval::const_eval::ConstEvalErr;
use rustc_const_eval::interpret::{ use rustc_const_eval::interpret::{
self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar, self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar, StackPopCleanup,
ScalarMaybeUninit, StackPopCleanup,
}; };
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::HirId; use rustc_hir::HirId;
@ -239,7 +238,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// Try to read the local as an immediate so that if it is representable as a scalar, we can // Try to read the local as an immediate so that if it is representable as a scalar, we can
// handle it as such, but otherwise, just return the value as is. // handle it as such, but otherwise, just return the value as is.
Some(match self.ecx.read_immediate_raw(&op, /*force*/ false) { Some(match self.ecx.read_immediate_raw(&op) {
Ok(Ok(imm)) => imm.into(), Ok(Ok(imm)) => imm.into(),
_ => op, _ => op,
}) })
@ -401,8 +400,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
let left_ty = left.ty(self.local_decls, self.tcx); let left_ty = left.ty(self.local_decls, self.tcx);
let left_size = self.ecx.layout_of(left_ty).ok()?.size; let left_size = self.ecx.layout_of(left_ty).ok()?.size;
let right_size = r.layout.size; let right_size = r.layout.size;
let r_bits = r.to_scalar().ok(); let r_bits = r.to_scalar().to_bits(right_size).ok();
let r_bits = r_bits.and_then(|r| r.to_bits(right_size).ok());
if r_bits.map_or(false, |b| b >= left_size.bits() as u128) { if r_bits.map_or(false, |b| b >= left_size.bits() as u128) {
debug!("check_binary_op: reporting assert for {:?}", source_info); debug!("check_binary_op: reporting assert for {:?}", source_info);
self.report_assert_as_lint( self.report_assert_as_lint(
@ -625,7 +623,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
TerminatorKind::Assert { expected, ref msg, ref cond, .. } => { TerminatorKind::Assert { expected, ref msg, ref cond, .. } => {
if let Some(ref value) = self.eval_operand(&cond, source_info) { if let Some(ref value) = self.eval_operand(&cond, source_info) {
trace!("assertion on {:?} should be {:?}", value, expected); trace!("assertion on {:?} should be {:?}", value, expected);
let expected = ScalarMaybeUninit::from(Scalar::from_bool(*expected)); let expected = Scalar::from_bool(*expected);
let value_const = self.ecx.read_scalar(&value).unwrap(); let value_const = self.ecx.read_scalar(&value).unwrap();
if expected != value_const { if expected != value_const {
enum DbgVal<T> { enum DbgVal<T> {

View file

@ -22,19 +22,14 @@ error[E0308]: mismatched types
LL | get_flag::<42, 0x5ad>(); LL | get_flag::<42, 0x5ad>();
| ^^^^^ expected `char`, found `u8` | ^^^^^ expected `char`, found `u8`
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/invalid-patterns.rs:38:21 --> $DIR/invalid-patterns.rs:38:32
| |
LL | get_flag::<false, { unsafe { char_raw.character } }>(); LL | get_flag::<false, { unsafe { char_raw.character } }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
__ __ __ __ │ ░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/invalid-patterns.rs:40:14 --> $DIR/invalid-patterns.rs:41:14
| |
LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
@ -45,7 +40,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/invalid-patterns.rs:42:14 --> $DIR/invalid-patterns.rs:43:14
| |
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
@ -55,16 +50,11 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character
42 │ B 42 │ B
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/invalid-patterns.rs:42:47 --> $DIR/invalid-patterns.rs:43:58
| |
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
__ __ __ __ │ ░░░░
}
error: aborting due to 8 previous errors error: aborting due to 8 previous errors

View file

@ -22,19 +22,14 @@ error[E0308]: mismatched types
LL | get_flag::<42, 0x5ad>(); LL | get_flag::<42, 0x5ad>();
| ^^^^^ expected `char`, found `u8` | ^^^^^ expected `char`, found `u8`
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/invalid-patterns.rs:38:21 --> $DIR/invalid-patterns.rs:38:32
| |
LL | get_flag::<false, { unsafe { char_raw.character } }>(); LL | get_flag::<false, { unsafe { char_raw.character } }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
__ __ __ __ │ ░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/invalid-patterns.rs:40:14 --> $DIR/invalid-patterns.rs:41:14
| |
LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
@ -45,7 +40,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/invalid-patterns.rs:42:14 --> $DIR/invalid-patterns.rs:43:14
| |
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
@ -55,16 +50,11 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character
42 │ B 42 │ B
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/invalid-patterns.rs:42:47 --> $DIR/invalid-patterns.rs:43:58
| |
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
__ __ __ __ │ ░░░░
}
error: aborting due to 8 previous errors error: aborting due to 8 previous errors

View file

@ -36,10 +36,12 @@ fn main() {
get_flag::<false, { unsafe { char_raw.character } }>(); get_flag::<false, { unsafe { char_raw.character } }>();
//~^ ERROR it is undefined behavior //~^ ERROR evaluation of constant value failed
//~| uninitialized
get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
//~^ ERROR it is undefined behavior //~^ ERROR it is undefined behavior
get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
//~^ ERROR it is undefined behavior //~^ ERROR evaluation of constant value failed
//~| uninitialized
//~| ERROR it is undefined behavior //~| ERROR it is undefined behavior
} }

View file

@ -1,13 +1,8 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/const-err4.rs:9:11 --> $DIR/const-err4.rs:9:21
| |
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
__ __ __ __ │ ░░░░
}
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,13 +1,8 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/const-err4.rs:9:11 --> $DIR/const-err4.rs:9:21
| |
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
__ __ __ __ __ __ __ __ │ ░░░░░░░░
}
error: aborting due to previous error error: aborting due to previous error

View file

@ -7,7 +7,8 @@ union Foo {
enum Bar { enum Bar {
Boo = [unsafe { Foo { b: () }.a }; 4][3], Boo = [unsafe { Foo { b: () }.a }; 4][3],
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| uninitialized
} }
fn main() { fn main() {

View file

@ -44,19 +44,14 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/const-pointer-values-in-various-types.rs:46:5 --> $DIR/const-pointer-values-in-various-types.rs:46:47
| |
LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 16, align: 8) {
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
}
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:49:43 --> $DIR/const-pointer-values-in-various-types.rs:50:43
| |
LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -65,7 +60,7 @@ LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:53:45 --> $DIR/const-pointer-values-in-various-types.rs:54:45
| |
LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 }; LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -74,7 +69,7 @@ LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:57:45 --> $DIR/const-pointer-values-in-various-types.rs:58:45
| |
LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 }; LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -83,7 +78,7 @@ LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:61:45 --> $DIR/const-pointer-values-in-various-types.rs:62:45
| |
LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 }; LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -91,19 +86,14 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/const-pointer-values-in-various-types.rs:65:5 --> $DIR/const-pointer-values-in-various-types.rs:66:47
| |
LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 16, align: 8) {
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
}
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:68:45 --> $DIR/const-pointer-values-in-various-types.rs:70:45
| |
LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -112,7 +102,7 @@ LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:72:45 --> $DIR/const-pointer-values-in-various-types.rs:74:45
| |
LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 }; LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -121,7 +111,7 @@ LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:76:47 --> $DIR/const-pointer-values-in-various-types.rs:78:47
| |
LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey }; LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -130,7 +120,7 @@ LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:80:47 --> $DIR/const-pointer-values-in-various-types.rs:82:47
| |
LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character }; LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -139,7 +129,7 @@ LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:84:39 --> $DIR/const-pointer-values-in-various-types.rs:86:39
| |
LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -148,7 +138,7 @@ LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:88:41 --> $DIR/const-pointer-values-in-various-types.rs:90:41
| |
LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }; LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -157,7 +147,7 @@ LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:92:41 --> $DIR/const-pointer-values-in-various-types.rs:94:41
| |
LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }; LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -166,7 +156,7 @@ LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:96:41 --> $DIR/const-pointer-values-in-various-types.rs:98:41
| |
LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }; LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -175,7 +165,7 @@ LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:100:43 --> $DIR/const-pointer-values-in-various-types.rs:102:43
| |
LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 }; LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -184,7 +174,7 @@ LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:104:39 --> $DIR/const-pointer-values-in-various-types.rs:106:39
| |
LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -193,7 +183,7 @@ LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:108:41 --> $DIR/const-pointer-values-in-various-types.rs:110:41
| |
LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -202,7 +192,7 @@ LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:112:41 --> $DIR/const-pointer-values-in-various-types.rs:114:41
| |
LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -211,7 +201,7 @@ LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:116:41 --> $DIR/const-pointer-values-in-various-types.rs:118:41
| |
LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -220,7 +210,7 @@ LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:120:43 --> $DIR/const-pointer-values-in-various-types.rs:122:43
| |
LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 }; LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -229,7 +219,7 @@ LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:124:41 --> $DIR/const-pointer-values-in-various-types.rs:126:41
| |
LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 }; LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -238,7 +228,7 @@ LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:128:41 --> $DIR/const-pointer-values-in-various-types.rs:130:41
| |
LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 }; LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -247,7 +237,7 @@ LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:132:43 --> $DIR/const-pointer-values-in-various-types.rs:134:43
| |
LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey }; LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -256,7 +246,7 @@ LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:136:43 --> $DIR/const-pointer-values-in-various-types.rs:138:43
| |
LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character }; LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -324,7 +314,7 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:49:43 --> $DIR/const-pointer-values-in-various-types.rs:50:43
| |
LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -335,7 +325,7 @@ LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:53:45 --> $DIR/const-pointer-values-in-various-types.rs:54:45
| |
LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 }; LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -346,7 +336,7 @@ LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:57:45 --> $DIR/const-pointer-values-in-various-types.rs:58:45
| |
LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 }; LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -357,7 +347,7 @@ LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:61:45 --> $DIR/const-pointer-values-in-various-types.rs:62:45
| |
LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 }; LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -368,7 +358,7 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:68:45 --> $DIR/const-pointer-values-in-various-types.rs:70:45
| |
LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -379,7 +369,7 @@ LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:72:45 --> $DIR/const-pointer-values-in-various-types.rs:74:45
| |
LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 }; LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -390,7 +380,7 @@ LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:76:47 --> $DIR/const-pointer-values-in-various-types.rs:78:47
| |
LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey }; LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -401,7 +391,7 @@ LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:80:47 --> $DIR/const-pointer-values-in-various-types.rs:82:47
| |
LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character }; LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -412,7 +402,7 @@ LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:84:39 --> $DIR/const-pointer-values-in-various-types.rs:86:39
| |
LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -423,7 +413,7 @@ LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:88:41 --> $DIR/const-pointer-values-in-various-types.rs:90:41
| |
LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }; LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -434,7 +424,7 @@ LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:92:41 --> $DIR/const-pointer-values-in-various-types.rs:94:41
| |
LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }; LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -445,7 +435,7 @@ LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:96:41 --> $DIR/const-pointer-values-in-various-types.rs:98:41
| |
LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }; LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -456,7 +446,7 @@ LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:100:43 --> $DIR/const-pointer-values-in-various-types.rs:102:43
| |
LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 }; LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -467,7 +457,7 @@ LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:104:39 --> $DIR/const-pointer-values-in-various-types.rs:106:39
| |
LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -478,7 +468,7 @@ LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:108:41 --> $DIR/const-pointer-values-in-various-types.rs:110:41
| |
LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -489,7 +479,7 @@ LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:112:41 --> $DIR/const-pointer-values-in-various-types.rs:114:41
| |
LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -500,7 +490,7 @@ LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:116:41 --> $DIR/const-pointer-values-in-various-types.rs:118:41
| |
LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -511,7 +501,7 @@ LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:120:43 --> $DIR/const-pointer-values-in-various-types.rs:122:43
| |
LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 }; LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -522,7 +512,7 @@ LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:124:41 --> $DIR/const-pointer-values-in-various-types.rs:126:41
| |
LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 }; LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -533,7 +523,7 @@ LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:128:41 --> $DIR/const-pointer-values-in-various-types.rs:130:41
| |
LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 }; LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -544,7 +534,7 @@ LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:132:43 --> $DIR/const-pointer-values-in-various-types.rs:134:43
| |
LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey }; LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -555,7 +545,7 @@ LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/const-pointer-values-in-various-types.rs:136:43 --> $DIR/const-pointer-values-in-various-types.rs:138:43
| |
LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character }; LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes

View file

@ -44,7 +44,8 @@ fn main() {
//~| WARN this was previously accepted by the compiler but is being phased out //~| WARN this was previously accepted by the compiler but is being phased out
const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| uninitialized
const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
//~^ ERROR any use of this value will cause an error //~^ ERROR any use of this value will cause an error
@ -63,7 +64,8 @@ fn main() {
//~| WARN this was previously accepted by the compiler but is being phased out //~| WARN this was previously accepted by the compiler but is being phased out
const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| uninitialized
const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
//~^ ERROR any use of this value will cause an error //~^ ERROR any use of this value will cause an error

View file

@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/alloc_intrinsic_uninit.rs:8:1 --> $DIR/alloc_intrinsic_uninit.rs:8:1
| |
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) }; LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
| ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) { = note: the raw bytes of the constant (size: 4, align: 4) {

View file

@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/alloc_intrinsic_uninit.rs:8:1 --> $DIR/alloc_intrinsic_uninit.rs:8:1
| |
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) }; LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
| ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) { = note: the raw bytes of the constant (size: 8, align: 8) {

View file

@ -6,12 +6,13 @@ enum E {
} }
const _: u8 = { const _: u8 = {
//~^ ERROR is undefined behavior
let mut e = E::A(1); let mut e = E::A(1);
let p = if let E::A(x) = &mut e { x as *mut u8 } else { unreachable!() }; let p = if let E::A(x) = &mut e { x as *mut u8 } else { unreachable!() };
// Make sure overwriting `e` uninitializes other bytes // Make sure overwriting `e` uninitializes other bytes
e = E::B; e = E::B;
unsafe { *p } unsafe { *p }
//~^ ERROR evaluation of constant value failed
//~| uninitialized
}; };
fn main() {} fn main() {}

View file

@ -1,13 +1,8 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum-overwrite.rs:8:1 --> $DIR/ub-enum-overwrite.rs:13:14
| |
LL | const _: u8 = { LL | unsafe { *p }
| ^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes | ^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 1, align: 1) {
__ │ ░
}
error: aborting due to previous error error: aborting due to previous error

View file

@ -57,19 +57,14 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:59:1 --> $DIR/ub-enum.rs:59:42
| |
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
__ __ __ __ │ ░░░░
}
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:63:1 --> $DIR/ub-enum.rs:64:1
| |
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -78,7 +73,7 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:81:1 --> $DIR/ub-enum.rs:82:1
| |
LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!`
@ -89,7 +84,7 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:83:1 --> $DIR/ub-enum.rs:84:1
| |
LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
@ -100,7 +95,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:91:1 --> $DIR/ub-enum.rs:92:1
| |
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
@ -111,13 +106,13 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran
} }
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:96:77 --> $DIR/ub-enum.rs:97:77
| |
LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:98:77 --> $DIR/ub-enum.rs:99:77
| |
LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
@ -171,7 +166,7 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:63:1 --> $DIR/ub-enum.rs:64:1
| |
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes

View file

@ -57,19 +57,14 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:59:1 --> $DIR/ub-enum.rs:59:42
| |
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
__ __ __ __ __ __ __ __ │ ░░░░░░░░
}
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:63:1 --> $DIR/ub-enum.rs:64:1
| |
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -78,7 +73,7 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:81:1 --> $DIR/ub-enum.rs:82:1
| |
LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!`
@ -89,7 +84,7 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:83:1 --> $DIR/ub-enum.rs:84:1
| |
LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
@ -100,7 +95,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:91:1 --> $DIR/ub-enum.rs:92:1
| |
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
@ -111,13 +106,13 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran
} }
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:96:77 --> $DIR/ub-enum.rs:97:77
| |
LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:98:77 --> $DIR/ub-enum.rs:99:77
| |
LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
@ -171,7 +166,7 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:63:1 --> $DIR/ub-enum.rs:64:1
| |
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes

View file

@ -57,7 +57,8 @@ union MaybeUninit<T: Copy> {
init: T, init: T,
} }
const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
//~^ ERROR is undefined behavior //~^ ERROR evaluation of constant value failed
//~| uninitialized
// Pointer value in an enum with a niche that is not just 0. // Pointer value in an enum with a niche that is not just 0.
const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };

View file

@ -1,35 +1,20 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-int-array.rs:14:1 --> $DIR/ub-int-array.rs:16:9
| |
LL | const UNINIT_INT_0: [u32; 3] = unsafe { LL | MaybeUninit { uninit: () }.init,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered uninitialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 12, align: 4) {
__ __ __ __ 01 00 00 00 02 00 00 00 │ ░░░░........
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-int-array.rs:23:1 --> $DIR/ub-int-array.rs:31:13
| |
LL | const UNINIT_INT_1: [u32; 3] = unsafe { LL | MaybeUninit { uninit: () }.init,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [1]: encountered uninitialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 12, align: 4) {
00 00 00 00 01 __ 01 01 02 02 __ 02 │ .....░....░.
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-int-array.rs:43:1 --> $DIR/ub-int-array.rs:57:13
| |
LL | const UNINIT_INT_2: [u32; 3] = unsafe { LL | MaybeUninit { uninit: () }.init,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [2]: encountered uninitialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 12, align: 4) {
00 00 00 00 01 01 01 01 02 02 02 __ │ ...........░
}
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -1,35 +1,20 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-int-array.rs:14:1 --> $DIR/ub-int-array.rs:16:9
| |
LL | const UNINIT_INT_0: [u32; 3] = unsafe { LL | MaybeUninit { uninit: () }.init,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered uninitialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 12, align: 4) {
__ __ __ __ 01 00 00 00 02 00 00 00 │ ░░░░........
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-int-array.rs:23:1 --> $DIR/ub-int-array.rs:31:13
| |
LL | const UNINIT_INT_1: [u32; 3] = unsafe { LL | MaybeUninit { uninit: () }.init,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [1]: encountered uninitialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 12, align: 4) {
00 00 00 00 01 __ 01 01 02 02 __ 02 │ .....░....░.
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-int-array.rs:43:1 --> $DIR/ub-int-array.rs:57:13
| |
LL | const UNINIT_INT_2: [u32; 3] = unsafe { LL | MaybeUninit { uninit: () }.init,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [2]: encountered uninitialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 12, align: 4) {
00 00 00 00 01 01 01 01 02 02 02 __ │ ...........░
}
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -12,17 +12,15 @@ union MaybeUninit<T: Copy> {
} }
const UNINIT_INT_0: [u32; 3] = unsafe { const UNINIT_INT_0: [u32; 3] = unsafe {
//~^ ERROR it is undefined behavior to use this value
//~| constructing invalid value at [0]: encountered uninitialized bytes
[ [
MaybeUninit { uninit: () }.init, MaybeUninit { uninit: () }.init,
//~^ ERROR evaluation of constant value failed
//~| uninitialized
1, 1,
2, 2,
] ]
}; };
const UNINIT_INT_1: [u32; 3] = unsafe { const UNINIT_INT_1: [u32; 3] = unsafe {
//~^ ERROR it is undefined behavior to use this value
//~| constructing invalid value at [1]: encountered uninitialized bytes
mem::transmute( mem::transmute(
[ [
0u8, 0u8,
@ -31,6 +29,8 @@ const UNINIT_INT_1: [u32; 3] = unsafe {
0u8, 0u8,
1u8, 1u8,
MaybeUninit { uninit: () }.init, MaybeUninit { uninit: () }.init,
//~^ ERROR evaluation of constant value failed
//~| uninitialized
1u8, 1u8,
1u8, 1u8,
2u8, 2u8,
@ -41,8 +41,6 @@ const UNINIT_INT_1: [u32; 3] = unsafe {
) )
}; };
const UNINIT_INT_2: [u32; 3] = unsafe { const UNINIT_INT_2: [u32; 3] = unsafe {
//~^ ERROR it is undefined behavior to use this value
//~| constructing invalid value at [2]: encountered uninitialized bytes
mem::transmute( mem::transmute(
[ [
0u8, 0u8,
@ -57,6 +55,8 @@ const UNINIT_INT_2: [u32; 3] = unsafe {
2u8, 2u8,
2u8, 2u8,
MaybeUninit { uninit: () }.init, MaybeUninit { uninit: () }.init,
//~^ ERROR evaluation of constant value failed
//~| uninitialized
] ]
) )
}; };

View file

@ -37,19 +37,14 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
00 00 00 00 │ .... 00 00 00 00 │ ....
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-nonnull.rs:33:1 --> $DIR/ub-nonnull.rs:33:36
| |
LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 1, align: 1) {
__ │ ░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-nonnull.rs:41:1 --> $DIR/ub-nonnull.rs:42:1
| |
LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30
@ -60,7 +55,7 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-nonnull.rs:47:1 --> $DIR/ub-nonnull.rs:48:1
| |
LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30

View file

@ -37,19 +37,14 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
00 00 00 00 00 00 00 00 │ ........ 00 00 00 00 00 00 00 00 │ ........
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-nonnull.rs:33:1 --> $DIR/ub-nonnull.rs:33:36
| |
LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 1, align: 1) {
__ │ ░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-nonnull.rs:41:1 --> $DIR/ub-nonnull.rs:42:1
| |
LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30
@ -60,7 +55,7 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-nonnull.rs:47:1 --> $DIR/ub-nonnull.rs:48:1
| |
LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30

View file

@ -31,7 +31,8 @@ union MaybeUninit<T: Copy> {
init: T, init: T,
} }
const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| uninitialized
// Also test other uses of rustc_layout_scalar_valid_range_start // Also test other uses of rustc_layout_scalar_valid_range_start

View file

@ -110,19 +110,14 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
39 05 00 00 │ 9... 39 05 00 00 │ 9...
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-ref-ptr.rs:53:1 --> $DIR/ub-ref-ptr.rs:53:41
| |
LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
__ __ __ __ │ ░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:56:1 --> $DIR/ub-ref-ptr.rs:57:1
| |
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
@ -132,19 +127,14 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
00 00 00 00 │ .... 00 00 00 00 │ ....
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-ref-ptr.rs:58:1 --> $DIR/ub-ref-ptr.rs:59:38
| |
LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a proper pointer or integer value | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 4, align: 4) {
__ __ __ __ │ ░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:60:1 --> $DIR/ub-ref-ptr.rs:62:1
| |
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
@ -155,7 +145,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:62:1 --> $DIR/ub-ref-ptr.rs:64:1
| |
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer

View file

@ -110,19 +110,14 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
39 05 00 00 00 00 00 00 │ 9....... 39 05 00 00 00 00 00 00 │ 9.......
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-ref-ptr.rs:53:1 --> $DIR/ub-ref-ptr.rs:53:41
| |
LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
__ __ __ __ __ __ __ __ │ ░░░░░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:56:1 --> $DIR/ub-ref-ptr.rs:57:1
| |
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
@ -132,19 +127,14 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
00 00 00 00 00 00 00 00 │ ........ 00 00 00 00 00 00 00 00 │ ........
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-ref-ptr.rs:58:1 --> $DIR/ub-ref-ptr.rs:59:38
| |
LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a proper pointer or integer value | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
__ __ __ __ __ __ __ __ │ ░░░░░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:60:1 --> $DIR/ub-ref-ptr.rs:62:1
| |
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
@ -155,7 +145,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:62:1 --> $DIR/ub-ref-ptr.rs:64:1
| |
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer

View file

@ -51,12 +51,14 @@ const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR it is undefined behavior to use this value
const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| uninitialized
const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR it is undefined behavior to use this value
const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| uninitialized
const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR it is undefined behavior to use this value
const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };

View file

@ -72,19 +72,14 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni
╾─allocN─╼ 01 00 00 00 │ ╾──╼.... ╾─allocN─╼ 01 00 00 00 │ ╾──╼....
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:63:1 --> $DIR/ub-wide-ptr.rs:63:1
| |
LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized reference | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 4) {
2a 00 00 00 __ __ __ __ │ *...░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:69:1 --> $DIR/ub-wide-ptr.rs:70:1
| |
LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
@ -95,7 +90,7 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:72:1 --> $DIR/ub-wide-ptr.rs:73:1
| |
LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) }; LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
@ -106,7 +101,7 @@ LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, is
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:75:1 --> $DIR/ub-wide-ptr.rs:76:1
| |
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -115,7 +110,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:79:1 --> $DIR/ub-wide-ptr.rs:80:1
| |
LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation)
@ -126,7 +121,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:82:1 --> $DIR/ub-wide-ptr.rs:83:1
| |
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -135,7 +130,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:87:1 --> $DIR/ub-wide-ptr.rs:88:1
| |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean
@ -146,7 +141,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:87:40 --> $DIR/ub-wide-ptr.rs:88:40
| |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@ -155,7 +150,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:95:1 --> $DIR/ub-wide-ptr.rs:96:1
| |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean
@ -166,7 +161,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:95:42 --> $DIR/ub-wide-ptr.rs:96:42
| |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@ -175,7 +170,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:100:1 --> $DIR/ub-wide-ptr.rs:101:1
| |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean
@ -186,7 +181,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:100:42 --> $DIR/ub-wide-ptr.rs:101:42
| |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@ -194,19 +189,14 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:109:1 --> $DIR/ub-wide-ptr.rs:110:1
| |
LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 4) {
2a 00 00 00 __ __ __ __ │ *...░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:117:1 --> $DIR/ub-wide-ptr.rs:119:1
| |
LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@ -217,7 +207,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:121:1 --> $DIR/ub-wide-ptr.rs:123:1
| |
LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@ -228,7 +218,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:125:1 --> $DIR/ub-wide-ptr.rs:127:1
| |
LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer
@ -239,25 +229,25 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u
} }
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:128:57 --> $DIR/ub-wide-ptr.rs:130:57
| |
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:131:57 --> $DIR/ub-wide-ptr.rs:133:57
| |
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:134:56 --> $DIR/ub-wide-ptr.rs:136:56
| |
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:137:1 --> $DIR/ub-wide-ptr.rs:139:1
| |
LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@ -268,7 +258,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:142:1 --> $DIR/ub-wide-ptr.rs:144:1
| |
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean
@ -279,7 +269,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:147:1 --> $DIR/ub-wide-ptr.rs:149:1
| |
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer
@ -290,7 +280,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:149:1 --> $DIR/ub-wide-ptr.rs:151:1
| |
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer
@ -301,13 +291,13 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm
} }
error[E0080]: could not evaluate static initializer error[E0080]: could not evaluate static initializer
--> $DIR/ub-wide-ptr.rs:155:5 --> $DIR/ub-wide-ptr.rs:157:5
| |
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
error[E0080]: could not evaluate static initializer error[E0080]: could not evaluate static initializer
--> $DIR/ub-wide-ptr.rs:159:5 --> $DIR/ub-wide-ptr.rs:161:5
| |
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
@ -339,7 +329,7 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:75:1 --> $DIR/ub-wide-ptr.rs:76:1
| |
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -350,7 +340,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:82:1 --> $DIR/ub-wide-ptr.rs:83:1
| |
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -361,7 +351,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:87:40 --> $DIR/ub-wide-ptr.rs:88:40
| |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@ -372,7 +362,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:95:42 --> $DIR/ub-wide-ptr.rs:96:42
| |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@ -383,7 +373,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:100:42 --> $DIR/ub-wide-ptr.rs:101:42
| |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors

View file

@ -72,19 +72,14 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni
╾───────allocN───────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ ╾───────allocN───────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:63:1 --> $DIR/ub-wide-ptr.rs:63:1
| |
LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized reference | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 16, align: 8) {
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:69:1 --> $DIR/ub-wide-ptr.rs:70:1
| |
LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
@ -95,7 +90,7 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:72:1 --> $DIR/ub-wide-ptr.rs:73:1
| |
LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) }; LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
@ -106,7 +101,7 @@ LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, is
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:75:1 --> $DIR/ub-wide-ptr.rs:76:1
| |
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -115,7 +110,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:79:1 --> $DIR/ub-wide-ptr.rs:80:1
| |
LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation)
@ -126,7 +121,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:82:1 --> $DIR/ub-wide-ptr.rs:83:1
| |
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -135,7 +130,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:87:1 --> $DIR/ub-wide-ptr.rs:88:1
| |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean
@ -146,7 +141,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:87:40 --> $DIR/ub-wide-ptr.rs:88:40
| |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@ -155,7 +150,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:95:1 --> $DIR/ub-wide-ptr.rs:96:1
| |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean
@ -166,7 +161,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:95:42 --> $DIR/ub-wide-ptr.rs:96:42
| |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@ -175,7 +170,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:100:1 --> $DIR/ub-wide-ptr.rs:101:1
| |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean
@ -186,7 +181,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:100:42 --> $DIR/ub-wide-ptr.rs:101:42
| |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@ -194,19 +189,14 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:109:1 --> $DIR/ub-wide-ptr.rs:110:1
| |
LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 16, align: 8) {
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:117:1 --> $DIR/ub-wide-ptr.rs:119:1
| |
LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@ -217,7 +207,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:121:1 --> $DIR/ub-wide-ptr.rs:123:1
| |
LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@ -228,7 +218,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:125:1 --> $DIR/ub-wide-ptr.rs:127:1
| |
LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer
@ -239,25 +229,25 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u
} }
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:128:57 --> $DIR/ub-wide-ptr.rs:130:57
| |
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:131:57 --> $DIR/ub-wide-ptr.rs:133:57
| |
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:134:56 --> $DIR/ub-wide-ptr.rs:136:56
| |
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:137:1 --> $DIR/ub-wide-ptr.rs:139:1
| |
LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
@ -268,7 +258,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:142:1 --> $DIR/ub-wide-ptr.rs:144:1
| |
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean
@ -279,7 +269,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:147:1 --> $DIR/ub-wide-ptr.rs:149:1
| |
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer
@ -290,7 +280,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:149:1 --> $DIR/ub-wide-ptr.rs:151:1
| |
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer
@ -301,13 +291,13 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm
} }
error[E0080]: could not evaluate static initializer error[E0080]: could not evaluate static initializer
--> $DIR/ub-wide-ptr.rs:155:5 --> $DIR/ub-wide-ptr.rs:157:5
| |
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
error[E0080]: could not evaluate static initializer error[E0080]: could not evaluate static initializer
--> $DIR/ub-wide-ptr.rs:159:5 --> $DIR/ub-wide-ptr.rs:161:5
| |
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
@ -339,7 +329,7 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:75:1 --> $DIR/ub-wide-ptr.rs:76:1
| |
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -350,7 +340,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:82:1 --> $DIR/ub-wide-ptr.rs:83:1
| |
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -361,7 +351,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:87:40 --> $DIR/ub-wide-ptr.rs:88:40
| |
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@ -372,7 +362,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:95:42 --> $DIR/ub-wide-ptr.rs:96:42
| |
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
@ -383,7 +373,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-wide-ptr.rs:100:42 --> $DIR/ub-wide-ptr.rs:101:42
| |
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors

View file

@ -61,7 +61,8 @@ const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::
const SLICE_VALID: &[u8] = unsafe { mem::transmute((&42u8, 1usize)) }; const SLICE_VALID: &[u8] = unsafe { mem::transmute((&42u8, 1usize)) };
// bad slice: length uninit // bad slice: length uninit
const SLICE_LENGTH_UNINIT: &[u8] = unsafe { const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| uninitialized
let uninit_len = MaybeUninit::<usize> { uninit: () }; let uninit_len = MaybeUninit::<usize> { uninit: () };
mem::transmute((42, uninit_len)) mem::transmute((42, uninit_len))
}; };
@ -107,7 +108,8 @@ const RAW_SLICE_VALID: *const [u8] = unsafe { mem::transmute((&42u8, 1usize)) };
const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, 999usize)) }; // ok because raw const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, 999usize)) }; // ok because raw
const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, usize::MAX)) }; // ok because raw const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, usize::MAX)) }; // ok because raw
const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| uninitialized
let uninit_len = MaybeUninit::<usize> { uninit: () }; let uninit_len = MaybeUninit::<usize> { uninit: () };
mem::transmute((42, uninit_len)) mem::transmute((42, uninit_len))
}; };

View file

@ -26,7 +26,8 @@ const fn read_field2() -> Field2 {
const fn read_field3() -> Field3 { const fn read_field3() -> Field3 {
const FIELD3: Field3 = unsafe { UNION.field3 }; const FIELD3: Field3 = unsafe { UNION.field3 };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| uninitialized
FIELD3 FIELD3
//~^ ERROR erroneous constant used [E0080] //~^ ERROR erroneous constant used [E0080]
} }

View file

@ -1,16 +1,11 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/union-const-eval-field.rs:28:5 --> $DIR/union-const-eval-field.rs:28:37
| |
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; LL | const FIELD3: Field3 = unsafe { UNION.field3 };
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
__ __ __ __ __ __ __ __ │ ░░░░░░░░
}
error[E0080]: erroneous constant used error[E0080]: erroneous constant used
--> $DIR/union-const-eval-field.rs:30:5 --> $DIR/union-const-eval-field.rs:31:5
| |
LL | FIELD3 LL | FIELD3
| ^^^^^^ referenced constant has errors | ^^^^^^ referenced constant has errors

View file

@ -11,11 +11,15 @@ union DummyUnion {
const UNION: DummyUnion = DummyUnion { field1: 1065353216 }; const UNION: DummyUnion = DummyUnion { field1: 1065353216 };
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR it is undefined behavior to use this value const FIELD3: Field3 = unsafe { UNION.field3 };
//~^ ERROR evaluation of constant value failed
//~| uninitialized
const FIELD_PATH: Struct = Struct { //~ ERROR it is undefined behavior to use this value const FIELD_PATH: Struct = Struct {
a: 42, a: 42,
b: unsafe { UNION.field3 }, b: unsafe { UNION.field3 },
//~^ ERROR evaluation of constant value failed
//~| uninitialized
}; };
struct Struct { struct Struct {
@ -23,10 +27,12 @@ struct Struct {
b: Field3, b: Field3,
} }
const FIELD_PATH2: Struct2 = Struct2 { //~ ERROR it is undefined behavior to use this value const FIELD_PATH2: Struct2 = Struct2 {
b: [ b: [
21, 21,
unsafe { UNION.field3 }, unsafe { UNION.field3 },
//~^ ERROR evaluation of constant value failed
//~| uninitialized
23, 23,
24, 24,
], ],

View file

@ -1,37 +1,20 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/union-ice.rs:14:1 --> $DIR/union-ice.rs:14:33
| |
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; LL | const FIELD3: Field3 = unsafe { UNION.field3 };
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 8) {
__ __ __ __ __ __ __ __ │ ░░░░░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/union-ice.rs:16:1 --> $DIR/union-ice.rs:20:17
| |
LL | const FIELD_PATH: Struct = Struct { LL | b: unsafe { UNION.field3 },
| ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .b: encountered uninitialized bytes, but expected initialized bytes | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 16, align: 8) {
__ __ __ __ __ __ __ __ 2a __ __ __ __ __ __ __ │ ░░░░░░░░*░░░░░░░
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/union-ice.rs:26:1 --> $DIR/union-ice.rs:33:18
| |
LL | const FIELD_PATH2: Struct2 = Struct2 { LL | unsafe { UNION.field3 },
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .b[1]: encountered uninitialized bytes | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 40, align: 8) {
0x00 │ 15 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ │ ........░░░░░░░░
0x10 │ 17 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 │ ................
0x20 │ 2a __ __ __ __ __ __ __ │ *░░░░░░░
}
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -9,16 +9,11 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
2a │ * 2a │ *
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/union-ub.rs:35:1 --> $DIR/union-ub.rs:35:36
| |
LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool}; LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 1, align: 1) {
__ │ ░
}
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -9,16 +9,11 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
2a │ * 2a │ *
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/union-ub.rs:35:1 --> $DIR/union-ub.rs:35:36
| |
LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool}; LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 1, align: 1) {
__ │ ░
}
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -33,7 +33,8 @@ union Bar {
const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
//~^ ERROR it is undefined behavior to use this value //~^ ERROR it is undefined behavior to use this value
const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool}; const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| uninitialized
// The value is not valid for any union variant, but that's fine // The value is not valid for any union variant, but that's fine
// unions are just a convenient way to transmute bits around // unions are just a convenient way to transmute bits around

View file

@ -8,13 +8,13 @@ error[E0080]: evaluation of constant value failed
--> $DIR/detect-extra-ub.rs:15:21 --> $DIR/detect-extra-ub.rs:15:21
| |
LL | let _x: usize = transmute(&3u8); LL | let _x: usize = transmute(&3u8);
| ^^^^^^^^^^^^^^^ constructing invalid value: encountered (potentially part of) a pointer, but expected plain (non-pointer) bytes | ^^^^^^^^^^^^^^^ constructing invalid value: encountered (potentially part of) a pointer, but expected an integer
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/detect-extra-ub.rs:22:30 --> $DIR/detect-extra-ub.rs:22:30
| |
LL | let _x: (usize, usize) = transmute(x); LL | let _x: (usize, usize) = transmute(x);
| ^^^^^^^^^^^^ constructing invalid value at .0: encountered (potentially part of) a pointer, but expected plain (non-pointer) bytes | ^^^^^^^^^^^^ constructing invalid value at .0: encountered (potentially part of) a pointer, but expected an integer
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/detect-extra-ub.rs:28:20 --> $DIR/detect-extra-ub.rs:28:20