mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
make read_immediate error immediately on uninit, so ImmTy can carry initialized Scalar
This commit is contained in:
parent
2e52fe01cf
commit
30fa931f92
@ -3,7 +3,7 @@ use crate::interpret::eval_nullary_intrinsic;
|
||||
use crate::interpret::{
|
||||
intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId,
|
||||
Immediate, InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking,
|
||||
ScalarMaybeUninit, StackPopCleanup,
|
||||
StackPopCleanup,
|
||||
};
|
||||
|
||||
use rustc_hir::def::DefKind;
|
||||
@ -170,10 +170,7 @@ pub(super) fn op_to_const<'tcx>(
|
||||
// see comment on `let try_as_immediate` above
|
||||
Err(imm) => match *imm {
|
||||
_ if imm.layout.is_zst() => ConstValue::ZeroSized,
|
||||
Immediate::Scalar(x) => match x {
|
||||
ScalarMaybeUninit::Scalar(s) => ConstValue::Scalar(s),
|
||||
ScalarMaybeUninit::Uninit => to_const_value(&op.assert_mem_place()),
|
||||
},
|
||||
Immediate::Scalar(x) => ConstValue::Scalar(x),
|
||||
Immediate::ScalarPair(a, b) => {
|
||||
debug!("ScalarPair(a: {:?}, b: {:?})", a, b);
|
||||
// We know `offset` is relative to the allocation, so we can use `into_parts`.
|
||||
|
@ -347,8 +347,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
};
|
||||
match intrinsic_name {
|
||||
sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => {
|
||||
let a = ecx.read_immediate(&args[0])?.to_scalar()?;
|
||||
let b = ecx.read_immediate(&args[1])?.to_scalar()?;
|
||||
let a = ecx.read_scalar(&args[0])?;
|
||||
let b = ecx.read_scalar(&args[1])?;
|
||||
let cmp = if intrinsic_name == sym::ptr_guaranteed_eq {
|
||||
ecx.guaranteed_eq(a, b)?
|
||||
} else {
|
||||
|
@ -3,7 +3,7 @@ use super::machine::CompileTimeEvalContext;
|
||||
use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES};
|
||||
use crate::interpret::{
|
||||
intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta,
|
||||
MemoryKind, PlaceTy, Scalar, ScalarMaybeUninit,
|
||||
MemoryKind, PlaceTy, Scalar,
|
||||
};
|
||||
use crate::interpret::{MPlaceTy, Value};
|
||||
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 {
|
||||
return Err(ValTreeCreationError::Other);
|
||||
};
|
||||
let val = val.to_scalar().unwrap();
|
||||
let val = val.to_scalar();
|
||||
*num_nodes += 1;
|
||||
|
||||
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 => {
|
||||
let scalar_int = valtree.unwrap_leaf();
|
||||
debug!("writing trivial valtree {:?} to place {:?}", scalar_int, place);
|
||||
ecx.write_immediate(
|
||||
Immediate::Scalar(ScalarMaybeUninit::Scalar(scalar_int.into())),
|
||||
&place.into(),
|
||||
)
|
||||
.unwrap();
|
||||
ecx.write_immediate(Immediate::Scalar(scalar_int.into()), &place.into()).unwrap();
|
||||
}
|
||||
ty::Ref(_, inner_ty, _) => {
|
||||
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() {
|
||||
ty::Slice(_) | ty::Str => {
|
||||
let len = valtree.unwrap_branch().len();
|
||||
let len_scalar =
|
||||
ScalarMaybeUninit::Scalar(Scalar::from_machine_usize(len as u64, &tcx));
|
||||
let len_scalar = Scalar::from_machine_usize(len as u64, &tcx);
|
||||
|
||||
Immediate::ScalarPair(
|
||||
ScalarMaybeUninit::from_maybe_pointer((*pointee_place).ptr, &tcx),
|
||||
Scalar::from_maybe_pointer((*pointee_place).ptr, &tcx),
|
||||
len_scalar,
|
||||
)
|
||||
}
|
||||
|
@ -123,10 +123,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
match src.layout.ty.kind() {
|
||||
// Floating point
|
||||
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) => {
|
||||
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
|
||||
_ => 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!(src.layout.ty.is_unsafe_ptr());
|
||||
return match **src {
|
||||
Immediate::ScalarPair(data, _) => Ok(data.check_init()?.into()),
|
||||
Immediate::ScalarPair(data, _) => Ok(data.into()),
|
||||
Immediate::Scalar(..) => span_bug!(
|
||||
self.cur_span(),
|
||||
"{:?} 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".
|
||||
let scalar = src.to_scalar()?;
|
||||
let scalar = src.to_scalar();
|
||||
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!(cast_ty.is_integral());
|
||||
|
||||
let scalar = src.to_scalar()?;
|
||||
let scalar = src.to_scalar();
|
||||
let ptr = scalar.to_pointer(self)?;
|
||||
match ptr.into_pointer_or_addr() {
|
||||
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(_));
|
||||
|
||||
// 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 = 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()) {
|
||||
(&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
|
||||
let val =
|
||||
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.
|
||||
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 (ty, old_trait) = self.get_ptr_vtable(old_vptr)?;
|
||||
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, _)) => {
|
||||
// Initial cast from sized to dyn trait
|
||||
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);
|
||||
self.write_immediate(val, dest)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayou
|
||||
use super::{
|
||||
AllocId, GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace,
|
||||
MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, PointerArithmetic, Provenance,
|
||||
Scalar, ScalarMaybeUninit, StackPopJump,
|
||||
Scalar, StackPopJump,
|
||||
};
|
||||
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))) => {
|
||||
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());
|
||||
}
|
||||
}
|
||||
LocalValue::Live(Operand::Immediate(Immediate::ScalarPair(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());
|
||||
}
|
||||
if let ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, _size)) = val2 {
|
||||
if let Scalar::Ptr(ptr, _size) = val2 {
|
||||
allocs.push(ptr.provenance.get_alloc_id());
|
||||
}
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
| sym::bitreverse => {
|
||||
let ty = substs.type_at(0);
|
||||
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 kind = match layout_of.abi {
|
||||
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)?;
|
||||
if overflowed {
|
||||
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 {
|
||||
throw_ub_format!("overflowing shift by {} in `{}`", r_val, intrinsic_name);
|
||||
} 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_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
|
||||
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 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 width_bits = u128::from(layout.size.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)?;
|
||||
}
|
||||
sym::assume => {
|
||||
let cond = self.read_scalar(&args[0])?.check_init()?.to_bool()?;
|
||||
let cond = self.read_scalar(&args[0])?.to_bool()?;
|
||||
if !cond {
|
||||
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
|
||||
// the fact that the operation has overflowed (if either is 0 no
|
||||
// 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;
|
||||
if first_term_positive {
|
||||
// Negative overflow not possible since the positive first term
|
||||
|
@ -21,7 +21,6 @@ use rustc_target::abi::{Align, HasDataLayout, Size};
|
||||
use super::{
|
||||
alloc_range, AllocId, AllocMap, AllocRange, Allocation, CheckInAllocMsg, GlobalAlloc, InterpCx,
|
||||
InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Provenance, Scalar,
|
||||
ScalarMaybeUninit,
|
||||
};
|
||||
|
||||
#[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.
|
||||
impl<'tcx, 'a, Prov: Provenance, Extra> AllocRefMut<'a, 'tcx, Prov, Extra> {
|
||||
/// `range` is relative to this allocation reference, not the base of the allocation.
|
||||
pub fn write_scalar(
|
||||
&mut self,
|
||||
range: AllocRange,
|
||||
val: ScalarMaybeUninit<Prov>,
|
||||
) -> InterpResult<'tcx> {
|
||||
pub fn write_scalar(&mut self, range: AllocRange, val: Scalar<Prov>) -> InterpResult<'tcx> {
|
||||
let range = self.range.subrange(range);
|
||||
debug!("write_scalar at {:?}{range:?}: {val:?}", self.alloc_id);
|
||||
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.
|
||||
pub fn write_ptr_sized(
|
||||
&mut self,
|
||||
offset: Size,
|
||||
val: ScalarMaybeUninit<Prov>,
|
||||
) -> InterpResult<'tcx> {
|
||||
pub fn write_ptr_sized(&mut self, offset: Size, val: Scalar<Prov>) -> InterpResult<'tcx> {
|
||||
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,
|
||||
range: AllocRange,
|
||||
read_provenance: bool,
|
||||
) -> InterpResult<'tcx, ScalarMaybeUninit<Prov>> {
|
||||
) -> InterpResult<'tcx, Scalar<Prov>> {
|
||||
let range = self.range.subrange(range);
|
||||
let res = self
|
||||
.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.
|
||||
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)
|
||||
}
|
||||
|
||||
/// `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(
|
||||
alloc_range(offset, self.tcx.data_layout().pointer_size),
|
||||
/*read_provenance*/ true,
|
||||
|
@ -1,11 +1,9 @@
|
||||
//! Functions concerning immediate values and operands, and reading from operands.
|
||||
//! All high-level functions to read from memory work on operands as sources.
|
||||
|
||||
use std::fmt::Write;
|
||||
|
||||
use rustc_hir::def::Namespace;
|
||||
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::{mir, ty};
|
||||
use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding};
|
||||
@ -14,7 +12,7 @@ use rustc_target::abi::{VariantIdx, Variants};
|
||||
use super::{
|
||||
alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, GlobalId,
|
||||
InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Place, PlaceTy, Pointer,
|
||||
Provenance, Scalar, ScalarMaybeUninit,
|
||||
Provenance, Scalar,
|
||||
};
|
||||
|
||||
/// An `Immediate` represents a single immediate self-contained Rust value.
|
||||
@ -27,23 +25,14 @@ use super::{
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Immediate<Prov: Provenance = AllocId> {
|
||||
/// A single scalar value (must have *initialized* `Scalar` ABI).
|
||||
/// FIXME: we also currently often use this for ZST.
|
||||
/// `ScalarMaybeUninit` should reject ZST, and we should use `Uninit` for them instead.
|
||||
Scalar(ScalarMaybeUninit<Prov>),
|
||||
Scalar(Scalar<Prov>),
|
||||
/// A pair of two scalar value (must have `ScalarPair` ABI where both fields are
|
||||
/// `Scalar::Initialized`).
|
||||
ScalarPair(ScalarMaybeUninit<Prov>, ScalarMaybeUninit<Prov>),
|
||||
ScalarPair(Scalar<Prov>, Scalar<Prov>),
|
||||
/// A value of fully uninitialized memory. Can have and size and layout.
|
||||
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> {
|
||||
#[inline(always)]
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
@ -69,41 +58,28 @@ impl<'tcx, Prov: Provenance> Immediate<Prov> {
|
||||
vtable: Pointer<Option<Prov>>,
|
||||
cx: &impl HasDataLayout,
|
||||
) -> Self {
|
||||
Immediate::ScalarPair(val.into(), ScalarMaybeUninit::from_maybe_pointer(vtable, cx))
|
||||
Immediate::ScalarPair(val.into(), Scalar::from_maybe_pointer(vtable, cx))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[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 {
|
||||
Immediate::Scalar(val) => val,
|
||||
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]
|
||||
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
|
||||
pub fn to_scalar(self) -> InterpResult<'tcx, 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>) {
|
||||
pub fn to_scalar_pair(self) -> (Scalar<Prov>, Scalar<Prov>) {
|
||||
match self {
|
||||
Immediate::ScalarPair(val1, val2) => (val1, val2),
|
||||
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
|
||||
@ -119,27 +95,17 @@ impl<Prov: Provenance> std::fmt::Display for ImmTy<'_, Prov> {
|
||||
/// Helper function for printing a scalar to a FmtPrinter
|
||||
fn p<'a, 'tcx, Prov: Provenance>(
|
||||
cx: FmtPrinter<'a, 'tcx>,
|
||||
s: ScalarMaybeUninit<Prov>,
|
||||
s: Scalar<Prov>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Result<FmtPrinter<'a, 'tcx>, std::fmt::Error> {
|
||||
match s {
|
||||
ScalarMaybeUninit::Scalar(Scalar::Int(int)) => {
|
||||
cx.pretty_print_const_scalar_int(int, ty, true)
|
||||
}
|
||||
ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, _sz)) => {
|
||||
Scalar::Int(int) => cx.pretty_print_const_scalar_int(int, ty, true),
|
||||
Scalar::Ptr(ptr, _sz) => {
|
||||
// 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
|
||||
// memory.
|
||||
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| {
|
||||
@ -269,7 +235,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
|
||||
#[inline]
|
||||
pub fn to_const_int(self) -> ConstInt {
|
||||
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())
|
||||
}
|
||||
}
|
||||
@ -327,7 +293,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
fn read_immediate_from_mplace_raw(
|
||||
&self,
|
||||
mplace: &MPlaceTy<'tcx, M::Provenance>,
|
||||
force: bool,
|
||||
) -> InterpResult<'tcx, Option<ImmTy<'tcx, M::Provenance>>> {
|
||||
if mplace.layout.is_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
|
||||
// check that walks over the type of `mplace` to make sure it is truly correct to treat this
|
||||
// like a `Scalar` (or `ScalarPair`).
|
||||
let scalar_layout = 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, .. }) => Some(s),
|
||||
Abi::Scalar(s) if force => Some(s.primitive()),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(s) = scalar_layout {
|
||||
let size = s.size(self);
|
||||
assert_eq!(size, mplace.layout.size, "abi::Scalar size does not match layout size");
|
||||
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 {
|
||||
Ok(match mplace.layout.abi {
|
||||
Abi::Scalar(abi::Scalar::Initialized { value: s, .. }) => {
|
||||
let size = s.size(self);
|
||||
assert_eq!(size, mplace.layout.size, "abi::Scalar size does not match layout size");
|
||||
let scalar = alloc.read_scalar(
|
||||
alloc_range(Size::ZERO, size),
|
||||
/*read_provenance*/ s.is_ptr(),
|
||||
)?;
|
||||
Some(ImmTy { imm: scalar.into(), layout: mplace.layout })
|
||||
}
|
||||
Abi::ScalarPair(
|
||||
abi::Scalar::Initialized { value: a, .. },
|
||||
abi::Scalar::Initialized { value: b, .. },
|
||||
) => Some((a, b)),
|
||||
Abi::ScalarPair(a, b) if force => Some((a.primitive(), b.primitive())),
|
||||
_ => None,
|
||||
};
|
||||
if let Some((a, b)) = scalar_pair_layout {
|
||||
// We checked `ptr_align` above, so all fields will have the alignment they need.
|
||||
// We would anyway check against `ptr_align.restrict_for_offset(b_offset)`,
|
||||
// which `ptr.offset(b_offset)` cannot possibly fail to satisfy.
|
||||
let (a_size, b_size) = (a.size(self), b.size(self));
|
||||
let b_offset = a_size.align_to(b.align(self).abi);
|
||||
assert!(b_offset.bytes() > 0); // in `operand_field` we use the offset to tell apart the fields
|
||||
let a_val = alloc.read_scalar(
|
||||
alloc_range(Size::ZERO, a_size),
|
||||
/*read_provenance*/ a.is_ptr(),
|
||||
)?;
|
||||
let b_val = alloc
|
||||
.read_scalar(alloc_range(b_offset, b_size), /*read_provenance*/ b.is_ptr())?;
|
||||
return Ok(Some(ImmTy {
|
||||
imm: Immediate::ScalarPair(a_val, b_val),
|
||||
layout: mplace.layout,
|
||||
}));
|
||||
}
|
||||
// Neither a scalar nor scalar pair.
|
||||
return Ok(None);
|
||||
) => {
|
||||
// We checked `ptr_align` above, so all fields will have the alignment they need.
|
||||
// We would anyway check against `ptr_align.restrict_for_offset(b_offset)`,
|
||||
// which `ptr.offset(b_offset)` cannot possibly fail to satisfy.
|
||||
let (a_size, b_size) = (a.size(self), b.size(self));
|
||||
let b_offset = a_size.align_to(b.align(self).abi);
|
||||
assert!(b_offset.bytes() > 0); // in `operand_field` we use the offset to tell apart the fields
|
||||
let a_val = alloc.read_scalar(
|
||||
alloc_range(Size::ZERO, a_size),
|
||||
/*read_provenance*/ a.is_ptr(),
|
||||
)?;
|
||||
let b_val = alloc.read_scalar(
|
||||
alloc_range(b_offset, b_size),
|
||||
/*read_provenance*/ b.is_ptr(),
|
||||
)?;
|
||||
Some(ImmTy {
|
||||
imm: Immediate::ScalarPair(a_val.into(), b_val.into()),
|
||||
layout: mplace.layout,
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
// Neither a scalar nor scalar pair.
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// 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.
|
||||
/// ConstProp needs it, though.
|
||||
pub fn read_immediate_raw(
|
||||
&self,
|
||||
src: &OpTy<'tcx, M::Provenance>,
|
||||
force: bool,
|
||||
) -> InterpResult<'tcx, Result<ImmTy<'tcx, M::Provenance>, MPlaceTy<'tcx, M::Provenance>>> {
|
||||
Ok(match src.try_as_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)
|
||||
} else {
|
||||
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.
|
||||
///
|
||||
/// If this suceeds, the `ImmTy` is never `Uninit`.
|
||||
#[inline(always)]
|
||||
pub fn read_immediate(
|
||||
&self,
|
||||
op: &OpTy<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
|
||||
if let Ok(imm) = self.read_immediate_raw(op, /*force*/ false)? {
|
||||
Ok(imm)
|
||||
} else {
|
||||
span_bug!(self.cur_span(), "primitive read failed for type: {:?}", op.layout.ty);
|
||||
if !matches!(
|
||||
op.layout.abi,
|
||||
Abi::Scalar(abi::Scalar::Initialized { .. })
|
||||
| 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
|
||||
pub fn read_scalar(
|
||||
&self,
|
||||
op: &OpTy<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx, ScalarMaybeUninit<M::Provenance>> {
|
||||
Ok(self.read_immediate(op)?.to_scalar_or_uninit())
|
||||
) -> InterpResult<'tcx, Scalar<M::Provenance>> {
|
||||
Ok(self.read_immediate(op)?.to_scalar())
|
||||
}
|
||||
|
||||
/// 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.
|
||||
Ok(match *tag_encoding {
|
||||
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.
|
||||
// (`tag_bits` itself is only used for error messages below.)
|
||||
let tag_bits = scalar
|
||||
@ -758,7 +724,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
(discr_val, index.0)
|
||||
}
|
||||
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,
|
||||
// discriminant (encoded in niche/tag) and variant index are the same.
|
||||
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 variant_index_relative_val =
|
||||
self.binary_op(mir::BinOp::Sub, &tag_val, &niche_start_val)?;
|
||||
let variant_index_relative = variant_index_relative_val
|
||||
.to_scalar()?
|
||||
.assert_bits(tag_val.layout.size);
|
||||
let variant_index_relative =
|
||||
variant_index_relative_val.to_scalar().assert_bits(tag_val.layout.size);
|
||||
// Check if this is in the range that indicates an actual discriminant.
|
||||
if variant_index_relative <= u128::from(variants_end - variants_start) {
|
||||
let variant_index_relative = u32::try_from(variant_index_relative)
|
||||
|
@ -329,21 +329,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
match left.layout.ty.kind() {
|
||||
ty::Char => {
|
||||
assert_eq!(left.layout.ty, right.layout.ty);
|
||||
let left = left.to_scalar()?;
|
||||
let right = right.to_scalar()?;
|
||||
let left = left.to_scalar();
|
||||
let right = right.to_scalar();
|
||||
Ok(self.binary_char_op(bin_op, left.to_char()?, right.to_char()?))
|
||||
}
|
||||
ty::Bool => {
|
||||
assert_eq!(left.layout.ty, right.layout.ty);
|
||||
let left = left.to_scalar()?;
|
||||
let right = right.to_scalar()?;
|
||||
let left = left.to_scalar();
|
||||
let right = right.to_scalar();
|
||||
Ok(self.binary_bool_op(bin_op, left.to_bool()?, right.to_bool()?))
|
||||
}
|
||||
ty::Float(fty) => {
|
||||
assert_eq!(left.layout.ty, right.layout.ty);
|
||||
let ty = left.layout.ty;
|
||||
let left = left.to_scalar()?;
|
||||
let right = right.to_scalar()?;
|
||||
let left = left.to_scalar();
|
||||
let right = right.to_scalar();
|
||||
Ok(match fty {
|
||||
FloatTy::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
|
||||
);
|
||||
|
||||
let l = left.to_scalar()?.to_bits(left.layout.size)?;
|
||||
let r = right.to_scalar()?.to_bits(right.layout.size)?;
|
||||
let l = left.to_scalar().to_bits(left.layout.size)?;
|
||||
let r = right.to_scalar().to_bits(right.layout.size)?;
|
||||
self.binary_int_op(bin_op, l, left.layout, r, right.layout)
|
||||
}
|
||||
_ 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::*;
|
||||
|
||||
let layout = val.layout;
|
||||
let val = val.to_scalar()?;
|
||||
let val = val.to_scalar();
|
||||
trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty);
|
||||
|
||||
match layout.ty.kind() {
|
||||
|
@ -13,7 +13,7 @@ use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding, Vari
|
||||
use super::{
|
||||
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg,
|
||||
ConstAlloc, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, OpTy, Operand,
|
||||
Pointer, Provenance, Scalar, ScalarMaybeUninit,
|
||||
Pointer, Provenance, Scalar,
|
||||
};
|
||||
|
||||
#[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.
|
||||
impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
|
||||
#[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>> {
|
||||
match **self {
|
||||
Operand::Indirect(mplace) => {
|
||||
@ -267,8 +265,6 @@ impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
|
||||
|
||||
#[inline(always)]
|
||||
#[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> {
|
||||
self.try_as_mplace().unwrap()
|
||||
}
|
||||
@ -312,7 +308,7 @@ where
|
||||
let layout = self.layout_of(pointee_type)?;
|
||||
let (ptr, meta) = match **val {
|
||||
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)),
|
||||
};
|
||||
|
||||
@ -467,7 +463,7 @@ where
|
||||
#[inline(always)]
|
||||
pub fn write_scalar(
|
||||
&mut self,
|
||||
val: impl Into<ScalarMaybeUninit<M::Provenance>>,
|
||||
val: impl Into<Scalar<M::Provenance>>,
|
||||
dest: &PlaceTy<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
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,
|
||||
// avoid force_allocation.
|
||||
let src = match self.read_immediate_raw(src, /*force*/ false)? {
|
||||
let src = match self.read_immediate_raw(src)? {
|
||||
Ok(src_val) => {
|
||||
assert!(!src.layout.is_unsized(), "cannot have unsized immediates");
|
||||
assert!(
|
||||
|
@ -129,8 +129,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
}
|
||||
|
||||
Assert { ref cond, expected, ref msg, target, cleanup } => {
|
||||
let cond_val =
|
||||
self.read_immediate(&self.eval_operand(cond, None)?)?.to_scalar()?.to_bool()?;
|
||||
let cond_val = self.read_scalar(&self.eval_operand(cond, None)?)?.to_bool()?;
|
||||
if expected == cond_val {
|
||||
self.go_to_block(target);
|
||||
} else {
|
||||
|
@ -20,8 +20,8 @@ use rustc_target::abi::{Abi, Scalar as ScalarAbi, Size, VariantIdx, Variants, Wr
|
||||
use std::hash::Hash;
|
||||
|
||||
use super::{
|
||||
alloc_range, CheckInAllocMsg, GlobalAlloc, Immediate, InterpCx, InterpResult, MPlaceTy,
|
||||
Machine, MemPlaceMeta, OpTy, Scalar, ScalarMaybeUninit, ValueVisitor,
|
||||
alloc_range, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy,
|
||||
Machine, MemPlaceMeta, OpTy, Scalar, ValueVisitor,
|
||||
};
|
||||
|
||||
macro_rules! throw_validation_failure {
|
||||
@ -304,6 +304,27 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
||||
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(
|
||||
&mut self,
|
||||
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>,
|
||||
kind: &str,
|
||||
) -> InterpResult<'tcx> {
|
||||
let value = try_validation!(
|
||||
self.ecx.read_immediate(value),
|
||||
self.path,
|
||||
err_unsup!(ReadPointerAsBytes) => { "part of a pointer" } expected { "a proper pointer or integer value" },
|
||||
);
|
||||
let place = self.ecx.ref_to_mplace(&self.read_immediate(value, &format!("a {kind}"))?)?;
|
||||
// Handle wide pointers.
|
||||
// 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() {
|
||||
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(())
|
||||
}
|
||||
|
||||
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
|
||||
/// at that type. Return `true` if the type is indeed 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;
|
||||
match ty.kind() {
|
||||
ty::Bool => {
|
||||
let value = self.read_scalar(value)?;
|
||||
let value = self.read_scalar(value, "a boolean")?;
|
||||
try_validation!(
|
||||
value.to_bool(),
|
||||
self.path,
|
||||
err_ub!(InvalidBool(..)) | err_ub!(InvalidUninitBytes(None)) =>
|
||||
err_ub!(InvalidBool(..)) =>
|
||||
{ "{:x}", value } expected { "a boolean" },
|
||||
);
|
||||
Ok(true)
|
||||
}
|
||||
ty::Char => {
|
||||
let value = self.read_scalar(value)?;
|
||||
let value = self.read_scalar(value, "a unicode scalar value")?;
|
||||
try_validation!(
|
||||
value.to_char(),
|
||||
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`)" },
|
||||
);
|
||||
Ok(true)
|
||||
}
|
||||
ty::Float(_) | ty::Int(_) | ty::Uint(_) => {
|
||||
let value = self.read_scalar(value)?;
|
||||
// NOTE: Keep this in sync with the array optimization for int/float
|
||||
// types below!
|
||||
try_validation!(
|
||||
value.check_init(),
|
||||
self.path,
|
||||
err_ub!(InvalidUninitBytes(..)) =>
|
||||
{ "{:x}", value } expected { "initialized bytes" }
|
||||
);
|
||||
let value = self.read_scalar(
|
||||
value,
|
||||
if matches!(ty.kind(), ty::Float(..)) {
|
||||
"a floating point number"
|
||||
} else {
|
||||
"an integer"
|
||||
},
|
||||
)?;
|
||||
// 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).
|
||||
let is_ptr = value.check_init().map_or(false, |v| matches!(v, Scalar::Ptr(..)));
|
||||
if is_ptr {
|
||||
if matches!(value, Scalar::Ptr(..)) {
|
||||
throw_validation_failure!(self.path,
|
||||
{ "{: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
|
||||
// actually enforce the strict rules for raw pointers (mostly because
|
||||
// that lets us re-use `ref_to_mplace`).
|
||||
let place = try_validation!(
|
||||
self.ecx.read_immediate(value).and_then(|ref i| self.ecx.ref_to_mplace(i)),
|
||||
self.path,
|
||||
err_ub!(InvalidUninitBytes(None)) => { "uninitialized raw pointer" },
|
||||
err_unsup!(ReadPointerAsBytes) => { "part of a pointer" } expected { "a proper pointer or integer value" },
|
||||
);
|
||||
let place =
|
||||
self.ecx.ref_to_mplace(&self.read_immediate(value, "a raw pointer")?)?;
|
||||
if place.layout.is_unsized() {
|
||||
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)
|
||||
}
|
||||
ty::FnPtr(_sig) => {
|
||||
let value = try_validation!(
|
||||
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" },
|
||||
);
|
||||
let value = self.read_scalar(value, "a function pointer")?;
|
||||
|
||||
// If we check references recursively, also check that this points to a function.
|
||||
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(
|
||||
&mut self,
|
||||
scalar: ScalarMaybeUninit<M::Provenance>,
|
||||
scalar: Scalar<M::Provenance>,
|
||||
scalar_layout: ScalarAbi,
|
||||
) -> 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 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 WrappingRange { start, end } = valid_range;
|
||||
let max_value = size.unsigned_int_max();
|
||||
assert!(end <= max_value);
|
||||
let value = try_validation!(
|
||||
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() {
|
||||
let bits = match scalar.try_to_int() {
|
||||
Ok(int) => int.assert_bits(size),
|
||||
Err(_) => {
|
||||
// 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.
|
||||
if start == 1 && end == max_value {
|
||||
// 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,
|
||||
{ "a potentially null pointer" }
|
||||
expected {
|
||||
@ -800,10 +762,11 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
||||
);
|
||||
}
|
||||
Abi::Scalar(scalar_layout) => {
|
||||
// We use a 'forced' read because we always need a `Immediate` here
|
||||
// and treating "partially uninit" as "fully uninit" is fine for us.
|
||||
let scalar = self.read_immediate_forced(op)?.to_scalar_or_uninit();
|
||||
self.visit_scalar(scalar, scalar_layout)?;
|
||||
if !scalar_layout.is_uninit_valid() {
|
||||
// There is something to check here.
|
||||
let scalar = self.read_scalar(op, "initiailized scalar value")?;
|
||||
self.visit_scalar(scalar, scalar_layout)?;
|
||||
}
|
||||
}
|
||||
Abi::ScalarPair(a_layout, b_layout) => {
|
||||
// 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
|
||||
// is subtle due to enums having ScalarPair layout, where one field
|
||||
// is the discriminant.
|
||||
if cfg!(debug_assertions) {
|
||||
// We use a 'forced' read because we always need a `Immediate` here
|
||||
// and treating "partially uninit" as "fully uninit" is fine for us.
|
||||
let (a, b) = self.read_immediate_forced(op)?.to_scalar_or_uninit_pair();
|
||||
if cfg!(debug_assertions)
|
||||
&& !a_layout.is_uninit_valid()
|
||||
&& !b_layout.is_uninit_valid()
|
||||
{
|
||||
// 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(b, b_layout)?;
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ use rustc_target::abi::{Align, HasDataLayout, Size};
|
||||
|
||||
use super::{
|
||||
read_target_uint, write_target_uint, AllocId, InterpError, InterpResult, Pointer, Provenance,
|
||||
ResourceExhaustionInfo, Scalar, ScalarMaybeUninit, ScalarSizeMismatch, UndefinedBehaviorInfo,
|
||||
UninitBytesAccess, UnsupportedOpInfo,
|
||||
ResourceExhaustionInfo, Scalar, ScalarSizeMismatch, UndefinedBehaviorInfo, UninitBytesAccess,
|
||||
UnsupportedOpInfo,
|
||||
};
|
||||
use crate::ty;
|
||||
|
||||
@ -437,16 +437,14 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
||||
cx: &impl HasDataLayout,
|
||||
range: AllocRange,
|
||||
read_provenance: bool,
|
||||
) -> AllocResult<ScalarMaybeUninit<Prov>> {
|
||||
) -> AllocResult<Scalar<Prov>> {
|
||||
if read_provenance {
|
||||
assert_eq!(range.size, cx.data_layout().pointer_size);
|
||||
}
|
||||
|
||||
// First and foremost, if anything is uninit, bail.
|
||||
if self.is_init(range).is_err() {
|
||||
// This inflates uninitialized bytes to the entire scalar, even if only a few
|
||||
// bytes are uninitialized.
|
||||
return Ok(ScalarMaybeUninit::Uninit);
|
||||
return Err(AllocError::InvalidUninitBytes(None));
|
||||
}
|
||||
|
||||
// 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 bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
|
||||
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,
|
||||
@ -465,7 +463,7 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
||||
// We just strip provenance.
|
||||
let bytes = self.get_bytes_even_more_internal(range);
|
||||
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.
|
||||
@ -477,7 +475,7 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
||||
// underlying bits.
|
||||
let bytes = self.get_bytes(cx, range)?;
|
||||
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.
|
||||
@ -492,17 +490,10 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
||||
&mut self,
|
||||
cx: &impl HasDataLayout,
|
||||
range: AllocRange,
|
||||
val: ScalarMaybeUninit<Prov>,
|
||||
val: Scalar<Prov>,
|
||||
) -> AllocResult {
|
||||
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
|
||||
// as-is into memory.
|
||||
let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::convert::TryFrom;
|
||||
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 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 fn_alloc_id = tcx.create_fn_alloc(instance);
|
||||
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::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 fn_alloc_id = tcx.create_fn_alloc(instance);
|
||||
let fn_ptr = Pointer::from(fn_alloc_id);
|
||||
ScalarMaybeUninit::from_pointer(fn_ptr, &tcx)
|
||||
Scalar::from_pointer(fn_ptr, &tcx)
|
||||
}
|
||||
VtblEntry::TraitVPtr(trait_ref) => {
|
||||
let super_trait_ref = 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 vptr = Pointer::from(supertrait_alloc_id);
|
||||
ScalarMaybeUninit::from_pointer(vptr, &tcx)
|
||||
Scalar::from_pointer(vptr, &tcx)
|
||||
}
|
||||
};
|
||||
vtable
|
||||
|
@ -28,7 +28,7 @@ use crate::MirPass;
|
||||
use rustc_const_eval::interpret::{
|
||||
self, compile_time_machine, AllocId, ConstAllocation, ConstValue, CtfeValidationMode, Frame,
|
||||
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.
|
||||
@ -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
|
||||
// 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(),
|
||||
_ => op,
|
||||
})
|
||||
@ -532,8 +532,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
let left_ty = left.ty(self.local_decls, self.tcx);
|
||||
let left_size = self.ecx.layout_of(left_ty).ok()?.size;
|
||||
let right_size = r.layout.size;
|
||||
let r_bits = r.to_scalar().ok();
|
||||
let r_bits = r_bits.and_then(|r| r.to_bits(right_size).ok());
|
||||
let r_bits = r.to_scalar().to_bits(right_size).ok();
|
||||
if r_bits.map_or(false, |b| b >= left_size.bits() as u128) {
|
||||
return None;
|
||||
}
|
||||
@ -562,7 +561,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
// and use it to do const-prop here and everywhere else
|
||||
// where it makes sense.
|
||||
if let interpret::Operand::Immediate(interpret::Immediate::Scalar(
|
||||
ScalarMaybeUninit::Scalar(scalar),
|
||||
scalar,
|
||||
)) = *value
|
||||
{
|
||||
*operand = self.operand_from_scalar(
|
||||
@ -675,7 +674,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
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)?;
|
||||
|
||||
match op {
|
||||
@ -689,7 +688,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
BinOp::Mul if const_arg.layout.ty.is_integral() && arg_value == 0 => {
|
||||
if let Rvalue::CheckedBinaryOp(_, _) = rvalue {
|
||||
let val = Immediate::ScalarPair(
|
||||
const_arg.to_scalar()?.into(),
|
||||
const_arg.to_scalar().into(),
|
||||
Scalar::from_bool(false).into(),
|
||||
);
|
||||
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
|
||||
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 {
|
||||
match *imm {
|
||||
interpret::Immediate::Scalar(ScalarMaybeUninit::Scalar(scalar)) => {
|
||||
interpret::Immediate::Scalar(scalar) => {
|
||||
*rval = Rvalue::Use(self.operand_from_scalar(
|
||||
scalar,
|
||||
value.layout.ty,
|
||||
source_info.span,
|
||||
));
|
||||
}
|
||||
Immediate::ScalarPair(
|
||||
ScalarMaybeUninit::Scalar(_),
|
||||
ScalarMaybeUninit::Scalar(_),
|
||||
) => {
|
||||
Immediate::ScalarPair(..) => {
|
||||
// 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.
|
||||
// FIXME: enable the general case stated above ^.
|
||||
@ -812,13 +808,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
}
|
||||
|
||||
match **op {
|
||||
interpret::Operand::Immediate(Immediate::Scalar(ScalarMaybeUninit::Scalar(s))) => {
|
||||
s.try_to_int().is_ok()
|
||||
interpret::Operand::Immediate(Immediate::Scalar(s)) => 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,
|
||||
}
|
||||
}
|
||||
@ -1079,7 +1072,7 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
|
||||
TerminatorKind::Assert { expected, ref mut cond, .. } => {
|
||||
if let Some(ref value) = self.eval_operand(&cond) {
|
||||
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();
|
||||
if expected != value_const {
|
||||
// Poison all places this operand references so that further code
|
||||
@ -1092,13 +1085,11 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
|
||||
}
|
||||
} else {
|
||||
if self.should_const_prop(value) {
|
||||
if let ScalarMaybeUninit::Scalar(scalar) = value_const {
|
||||
*cond = self.operand_from_scalar(
|
||||
scalar,
|
||||
self.tcx.types.bool,
|
||||
source_info.span,
|
||||
);
|
||||
}
|
||||
*cond = self.operand_from_scalar(
|
||||
value_const,
|
||||
self.tcx.types.bool,
|
||||
source_info.span,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,7 @@ use crate::const_prop::ConstPropMode;
|
||||
use crate::MirLint;
|
||||
use rustc_const_eval::const_eval::ConstEvalErr;
|
||||
use rustc_const_eval::interpret::{
|
||||
self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar,
|
||||
ScalarMaybeUninit, StackPopCleanup,
|
||||
self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar, StackPopCleanup,
|
||||
};
|
||||
use rustc_hir::def::DefKind;
|
||||
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
|
||||
// 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(),
|
||||
_ => op,
|
||||
})
|
||||
@ -401,8 +400,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
let left_ty = left.ty(self.local_decls, self.tcx);
|
||||
let left_size = self.ecx.layout_of(left_ty).ok()?.size;
|
||||
let right_size = r.layout.size;
|
||||
let r_bits = r.to_scalar().ok();
|
||||
let r_bits = r_bits.and_then(|r| r.to_bits(right_size).ok());
|
||||
let r_bits = r.to_scalar().to_bits(right_size).ok();
|
||||
if r_bits.map_or(false, |b| b >= left_size.bits() as u128) {
|
||||
debug!("check_binary_op: reporting assert for {:?}", source_info);
|
||||
self.report_assert_as_lint(
|
||||
@ -625,7 +623,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
|
||||
TerminatorKind::Assert { expected, ref msg, ref cond, .. } => {
|
||||
if let Some(ref value) = self.eval_operand(&cond, source_info) {
|
||||
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();
|
||||
if expected != value_const {
|
||||
enum DbgVal<T> {
|
||||
|
@ -22,19 +22,14 @@ error[E0308]: mismatched types
|
||||
LL | get_flag::<42, 0x5ad>();
|
||||
| ^^^^^ expected `char`, found `u8`
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/invalid-patterns.rs:38:21
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/invalid-patterns.rs:38:32
|
||||
|
|
||||
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`)
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ │ ░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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'>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/invalid-patterns.rs:42:14
|
||||
--> $DIR/invalid-patterns.rs:43:14
|
||||
|
|
||||
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/invalid-patterns.rs:42:47
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/invalid-patterns.rs:43:58
|
||||
|
|
||||
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`)
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ │ ░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
@ -22,19 +22,14 @@ error[E0308]: mismatched types
|
||||
LL | get_flag::<42, 0x5ad>();
|
||||
| ^^^^^ expected `char`, found `u8`
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/invalid-patterns.rs:38:21
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/invalid-patterns.rs:38:32
|
||||
|
|
||||
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`)
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ │ ░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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'>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/invalid-patterns.rs:42:14
|
||||
--> $DIR/invalid-patterns.rs:43:14
|
||||
|
|
||||
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/invalid-patterns.rs:42:47
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/invalid-patterns.rs:43:58
|
||||
|
|
||||
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`)
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ │ ░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
@ -36,10 +36,12 @@ fn main() {
|
||||
|
||||
|
||||
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'>();
|
||||
//~^ ERROR it is undefined behavior
|
||||
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
|
||||
}
|
||||
|
@ -1,13 +1,8 @@
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const-err4.rs:9:11
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/const-err4.rs:9:21
|
||||
|
|
||||
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ │ ░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,13 +1,8 @@
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const-err4.rs:9:11
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/const-err4.rs:9:21
|
||||
|
|
||||
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ __ __ __ __ │ ░░░░░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -7,7 +7,8 @@ union Foo {
|
||||
|
||||
enum Bar {
|
||||
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() {
|
||||
|
@ -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!
|
||||
= 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
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:46:5
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $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 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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 };
|
||||
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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!
|
||||
= 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
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:65:5
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $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 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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 };
|
||||
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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 };
|
||||
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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 };
|
||||
| -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
@ -44,7 +44,8 @@ fn main() {
|
||||
//~| 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 };
|
||||
//~^ 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 };
|
||||
//~^ 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
|
||||
|
||||
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 };
|
||||
//~^ ERROR any use of this value will cause an error
|
||||
|
@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/alloc_intrinsic_uninit.rs:8:1
|
||||
|
|
||||
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 raw bytes of the constant (size: 4, align: 4) {
|
||||
|
@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/alloc_intrinsic_uninit.rs:8:1
|
||||
|
|
||||
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 raw bytes of the constant (size: 8, align: 8) {
|
||||
|
@ -6,12 +6,13 @@ enum E {
|
||||
}
|
||||
|
||||
const _: u8 = {
|
||||
//~^ ERROR is undefined behavior
|
||||
let mut e = E::A(1);
|
||||
let p = if let E::A(x) = &mut e { x as *mut u8 } else { unreachable!() };
|
||||
// Make sure overwriting `e` uninitializes other bytes
|
||||
e = E::B;
|
||||
unsafe { *p }
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~| uninitialized
|
||||
};
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,13 +1,8 @@
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-enum-overwrite.rs:8:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-enum-overwrite.rs:13:14
|
||||
|
|
||||
LL | const _: u8 = {
|
||||
| ^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ │ ░
|
||||
}
|
||||
LL | unsafe { *p }
|
||||
| ^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -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!
|
||||
= 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
|
||||
--> $DIR/ub-enum.rs:59:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-enum.rs:59:42
|
||||
|
|
||||
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ │ ░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-enum.rs:83:1
|
||||
--> $DIR/ub-enum.rs:84:1
|
||||
|
|
||||
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
|
||||
@ -100,7 +95,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute
|
||||
}
|
||||
|
||||
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) }));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
|
||||
@ -171,7 +166,7 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
|
||||
|
||||
Future breakage diagnostic:
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
@ -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!
|
||||
= 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
|
||||
--> $DIR/ub-enum.rs:59:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-enum.rs:59:42
|
||||
|
|
||||
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ __ __ __ __ │ ░░░░░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-enum.rs:83:1
|
||||
--> $DIR/ub-enum.rs:84:1
|
||||
|
|
||||
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
|
||||
@ -100,7 +95,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute
|
||||
}
|
||||
|
||||
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) }));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
|
||||
@ -171,7 +166,7 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
|
||||
|
||||
Future breakage diagnostic:
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
@ -57,7 +57,8 @@ union MaybeUninit<T: Copy> {
|
||||
init: T,
|
||||
}
|
||||
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.
|
||||
const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
|
||||
|
@ -1,35 +1,20 @@
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-int-array.rs:14:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-int-array.rs:16:9
|
||||
|
|
||||
LL | const UNINIT_INT_0: [u32; 3] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered uninitialized bytes
|
||||
|
|
||||
= 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 │ ░░░░........
|
||||
}
|
||||
LL | MaybeUninit { uninit: () }.init,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-int-array.rs:23:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-int-array.rs:31:13
|
||||
|
|
||||
LL | const UNINIT_INT_1: [u32; 3] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [1]: encountered uninitialized bytes
|
||||
|
|
||||
= 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 │ .....░....░.
|
||||
}
|
||||
LL | MaybeUninit { uninit: () }.init,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-int-array.rs:43:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-int-array.rs:57:13
|
||||
|
|
||||
LL | const UNINIT_INT_2: [u32; 3] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [2]: encountered uninitialized bytes
|
||||
|
|
||||
= 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 __ │ ...........░
|
||||
}
|
||||
LL | MaybeUninit { uninit: () }.init,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -1,35 +1,20 @@
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-int-array.rs:14:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-int-array.rs:16:9
|
||||
|
|
||||
LL | const UNINIT_INT_0: [u32; 3] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered uninitialized bytes
|
||||
|
|
||||
= 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 │ ░░░░........
|
||||
}
|
||||
LL | MaybeUninit { uninit: () }.init,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-int-array.rs:23:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-int-array.rs:31:13
|
||||
|
|
||||
LL | const UNINIT_INT_1: [u32; 3] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [1]: encountered uninitialized bytes
|
||||
|
|
||||
= 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 │ .....░....░.
|
||||
}
|
||||
LL | MaybeUninit { uninit: () }.init,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-int-array.rs:43:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-int-array.rs:57:13
|
||||
|
|
||||
LL | const UNINIT_INT_2: [u32; 3] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [2]: encountered uninitialized bytes
|
||||
|
|
||||
= 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 __ │ ...........░
|
||||
}
|
||||
LL | MaybeUninit { uninit: () }.init,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -12,17 +12,15 @@ union MaybeUninit<T: Copy> {
|
||||
}
|
||||
|
||||
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,
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~| uninitialized
|
||||
1,
|
||||
2,
|
||||
]
|
||||
};
|
||||
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(
|
||||
[
|
||||
0u8,
|
||||
@ -31,6 +29,8 @@ const UNINIT_INT_1: [u32; 3] = unsafe {
|
||||
0u8,
|
||||
1u8,
|
||||
MaybeUninit { uninit: () }.init,
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~| uninitialized
|
||||
1u8,
|
||||
1u8,
|
||||
2u8,
|
||||
@ -41,8 +41,6 @@ const UNINIT_INT_1: [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(
|
||||
[
|
||||
0u8,
|
||||
@ -57,6 +55,8 @@ const UNINIT_INT_2: [u32; 3] = unsafe {
|
||||
2u8,
|
||||
2u8,
|
||||
MaybeUninit { uninit: () }.init,
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~| uninitialized
|
||||
]
|
||||
)
|
||||
};
|
||||
|
@ -37,19 +37,14 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
|
||||
00 00 00 00 │ ....
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-nonnull.rs:33:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-nonnull.rs:33:36
|
||||
|
|
||||
LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ │ ░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-nonnull.rs:47:1
|
||||
--> $DIR/ub-nonnull.rs:48:1
|
||||
|
|
||||
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
|
||||
|
@ -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
|
||||
--> $DIR/ub-nonnull.rs:33:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-nonnull.rs:33:36
|
||||
|
|
||||
LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ │ ░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-nonnull.rs:47:1
|
||||
--> $DIR/ub-nonnull.rs:48:1
|
||||
|
|
||||
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
|
||||
|
@ -31,7 +31,8 @@ union MaybeUninit<T: Copy> {
|
||||
init: T,
|
||||
}
|
||||
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
|
||||
|
||||
|
@ -110,19 +110,14 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
|
||||
39 05 00 00 │ 9...
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:53:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-ref-ptr.rs:53:41
|
||||
|
|
||||
LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ │ ░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ 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 │ ....
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:58:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-ref-ptr.rs:59:38
|
||||
|
|
||||
LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a proper pointer or integer value
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ │ ░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-ref-ptr.rs:62:1
|
||||
--> $DIR/ub-ref-ptr.rs:64:1
|
||||
|
|
||||
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer
|
||||
|
@ -110,19 +110,14 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
|
||||
39 05 00 00 00 00 00 00 │ 9.......
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:53:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-ref-ptr.rs:53:41
|
||||
|
|
||||
LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ __ __ __ __ │ ░░░░░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-ref-ptr.rs:58:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-ref-ptr.rs:59:38
|
||||
|
|
||||
LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a proper pointer or integer value
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ __ __ __ __ │ ░░░░░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-ref-ptr.rs:62:1
|
||||
--> $DIR/ub-ref-ptr.rs:64:1
|
||||
|
|
||||
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer
|
||||
|
@ -51,12 +51,14 @@ const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
|
||||
//~^ ERROR it is undefined behavior to use this value
|
||||
|
||||
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) };
|
||||
//~^ ERROR it is undefined behavior to use this value
|
||||
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) };
|
||||
//~^ ERROR it is undefined behavior to use this value
|
||||
const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
|
||||
|
@ -72,19 +72,14 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni
|
||||
╾─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
|
||||
|
|
||||
LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized reference
|
||||
|
|
||||
= 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 __ __ __ __ │ *...░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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) }];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-wide-ptr.rs:87:40
|
||||
--> $DIR/ub-wide-ptr.rs:88:40
|
||||
|
|
||||
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
|
||||
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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]);
|
||||
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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) }]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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) }]);
|
||||
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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!
|
||||
= 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
|
||||
--> $DIR/ub-wide-ptr.rs:109:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-wide-ptr.rs:110:1
|
||||
|
|
||||
LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer
|
||||
|
|
||||
= 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 __ __ __ __ │ *...░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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))) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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))) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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))) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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])) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
|
||||
|
||||
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])) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
|
||||
|
||||
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])) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
|
||||
|
||||
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]))) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-wide-ptr.rs:155:5
|
||||
--> $DIR/ub-wide-ptr.rs:157:5
|
||||
|
|
||||
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
||||
|
||||
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))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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) }];
|
||||
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
@ -372,7 +362,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
|
||||
|
||||
Future breakage diagnostic:
|
||||
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]);
|
||||
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
@ -383,7 +373,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
|
||||
|
||||
Future breakage diagnostic:
|
||||
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) }]);
|
||||
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
|
@ -72,19 +72,14 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni
|
||||
╾───────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
|
||||
|
|
||||
LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized reference
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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) }];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-wide-ptr.rs:87:40
|
||||
--> $DIR/ub-wide-ptr.rs:88:40
|
||||
|
|
||||
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
|
||||
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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]);
|
||||
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>
|
||||
|
||||
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) }]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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) }]);
|
||||
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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!
|
||||
= 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
|
||||
--> $DIR/ub-wide-ptr.rs:109:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-wide-ptr.rs:110:1
|
||||
|
|
||||
LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized raw pointer
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
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))) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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))) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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))) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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])) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
|
||||
|
||||
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])) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
|
||||
|
||||
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])) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
|
||||
|
||||
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]))) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/ub-wide-ptr.rs:155:5
|
||||
--> $DIR/ub-wide-ptr.rs:157:5
|
||||
|
|
||||
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
||||
|
||||
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))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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)) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:
|
||||
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) }];
|
||||
| ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
@ -372,7 +362,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
|
||||
|
||||
Future breakage diagnostic:
|
||||
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]);
|
||||
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
@ -383,7 +373,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
|
||||
|
||||
Future breakage diagnostic:
|
||||
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) }]);
|
||||
| -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
|
@ -61,7 +61,8 @@ const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::
|
||||
const SLICE_VALID: &[u8] = unsafe { mem::transmute((&42u8, 1usize)) };
|
||||
// bad slice: length uninit
|
||||
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: () };
|
||||
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_MUCH_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, usize::MAX)) }; // ok because raw
|
||||
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: () };
|
||||
mem::transmute((42, uninit_len))
|
||||
};
|
||||
|
@ -26,7 +26,8 @@ const fn read_field2() -> Field2 {
|
||||
|
||||
const fn read_field3() -> Field3 {
|
||||
const FIELD3: Field3 = unsafe { UNION.field3 };
|
||||
//~^ ERROR it is undefined behavior to use this value
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~| uninitialized
|
||||
FIELD3
|
||||
//~^ ERROR erroneous constant used [E0080]
|
||||
}
|
||||
|
@ -1,16 +1,11 @@
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/union-const-eval-field.rs:28:5
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/union-const-eval-field.rs:28:37
|
||||
|
|
||||
LL | const FIELD3: Field3 = unsafe { UNION.field3 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ __ __ __ __ │ ░░░░░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: erroneous constant used
|
||||
--> $DIR/union-const-eval-field.rs:30:5
|
||||
--> $DIR/union-const-eval-field.rs:31:5
|
||||
|
|
||||
LL | FIELD3
|
||||
| ^^^^^^ referenced constant has errors
|
||||
|
@ -11,11 +11,15 @@ union DummyUnion {
|
||||
|
||||
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,
|
||||
b: unsafe { UNION.field3 },
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~| uninitialized
|
||||
};
|
||||
|
||||
struct Struct {
|
||||
@ -23,10 +27,12 @@ struct Struct {
|
||||
b: Field3,
|
||||
}
|
||||
|
||||
const FIELD_PATH2: Struct2 = Struct2 { //~ ERROR it is undefined behavior to use this value
|
||||
const FIELD_PATH2: Struct2 = Struct2 {
|
||||
b: [
|
||||
21,
|
||||
unsafe { UNION.field3 },
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~| uninitialized
|
||||
23,
|
||||
24,
|
||||
],
|
||||
|
@ -1,37 +1,20 @@
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/union-ice.rs:14:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/union-ice.rs:14:33
|
||||
|
|
||||
LL | const FIELD3: Field3 = unsafe { UNION.field3 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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) {
|
||||
__ __ __ __ __ __ __ __ │ ░░░░░░░░
|
||||
}
|
||||
| ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/union-ice.rs:16:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/union-ice.rs:20:17
|
||||
|
|
||||
LL | const FIELD_PATH: Struct = Struct {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .b: encountered uninitialized bytes, but expected initialized bytes
|
||||
|
|
||||
= 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 __ __ __ __ __ __ __ │ ░░░░░░░░*░░░░░░░
|
||||
}
|
||||
LL | b: unsafe { UNION.field3 },
|
||||
| ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/union-ice.rs:26:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/union-ice.rs:33:18
|
||||
|
|
||||
LL | const FIELD_PATH2: Struct2 = Struct2 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .b[1]: encountered uninitialized bytes
|
||||
|
|
||||
= 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 __ __ __ __ __ __ __ │ *░░░░░░░
|
||||
}
|
||||
LL | unsafe { UNION.field3 },
|
||||
| ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -9,16 +9,11 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
|
||||
2a │ *
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/union-ub.rs:35:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/union-ub.rs:35:36
|
||||
|
|
||||
LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a boolean
|
||||
|
|
||||
= 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) {
|
||||
__ │ ░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -9,16 +9,11 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
|
||||
2a │ *
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/union-ub.rs:35:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/union-ub.rs:35:36
|
||||
|
|
||||
LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a boolean
|
||||
|
|
||||
= 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) {
|
||||
__ │ ░
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -33,7 +33,8 @@ union Bar {
|
||||
const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
|
||||
//~^ ERROR it is undefined behavior to use this value
|
||||
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
|
||||
// unions are just a convenient way to transmute bits around
|
||||
|
@ -8,13 +8,13 @@ error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:15:21
|
||||
|
|
||||
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
|
||||
--> $DIR/detect-extra-ub.rs:22:30
|
||||
|
|
||||
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
|
||||
--> $DIR/detect-extra-ub.rs:28:20
|
||||
|
Loading…
Reference in New Issue
Block a user