diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index 2e6cbb131ef3..473ba848a583 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -299,29 +299,35 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
(&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
let val = self.read_immediate(src)?;
+ let (old_data, old_vptr) = val.to_scalar_pair()?;
+ let old_vptr = self.scalar_to_ptr(old_vptr)?;
if data_a.principal_def_id() == data_b.principal_def_id() {
return self.write_immediate(*val, dest);
}
// trait upcasting coercion
- let vptr_entry_idx = self.tcx.vtable_trait_upcasting_coercion_new_vptr_slot((
+ let Some(vptr_entry_idx) = self.tcx.vtable_trait_upcasting_coercion_new_vptr_slot((
src_pointee_ty,
dest_pointee_ty,
- ));
+ )) else {
+ return self.write_immediate(*val, dest);
+ };
- if let Some(entry_idx) = vptr_entry_idx {
- let entry_idx = u64::try_from(entry_idx).unwrap();
- let (old_data, old_vptr) = val.to_scalar_pair()?;
- let old_vptr = self.scalar_to_ptr(old_vptr)?;
- let new_vptr = self
- .read_new_vtable_after_trait_upcasting_from_vtable(old_vptr, entry_idx)?;
- self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest)
- } else {
- self.write_immediate(*val, dest)
- }
+ let (ty, _) = self.get_ptr_vtable(old_vptr)?;
+ let Some(ty::VtblEntry::TraitVPtr(new_trait)) = self.get_vtable_entries(old_vptr)?.get(vptr_entry_idx) else {
+ throw_ub_format!(
+ "upcasting to index {vptr_entry_idx} of vtable {old_vptr} but \
+ that vtable is too small or does not have an upcast-vtable at that index"
+ )
+ };
+ let new_trait = new_trait.map_bound(|trait_ref| {
+ ty::ExistentialTraitRef::erase_self_ty(*self.tcx, trait_ref)
+ });
+ let new_vptr = self.get_vtable_ptr(ty, Some(new_trait))?;
+ self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest)
}
(_, &ty::Dynamic(ref data, _)) => {
// Initial cast from sized to dyn trait
- let vtable = self.get_vtable(src_pointee_ty, data.principal())?;
+ let vtable = self.get_vtable_ptr(src_pointee_ty, data.principal())?;
let ptr = self.read_immediate(src)?.to_scalar()?;
let val = Immediate::new_dyn_trait(ptr, vtable, &*self.tcx);
self.write_immediate(val, dest)
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 45928d7b02e3..fdf243c4108d 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -631,7 +631,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ty::Dynamic(..) => {
let vtable = self.scalar_to_ptr(metadata.unwrap_meta())?;
// Read size and align from vtable (already checks size).
- Ok(Some(self.read_size_and_align_from_vtable(vtable)?))
+ Ok(Some(self.get_vtable_size_and_align(vtable)?))
}
ty::Slice(_) | ty::Str => {
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 0287c180e94b..5e49e6a4f084 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -16,7 +16,7 @@ use std::ptr;
use rustc_ast::Mutability;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::mir::display_allocation;
-use rustc_middle::ty::{Instance, ParamEnv, TyCtxt};
+use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
use rustc_target::abi::{Align, HasDataLayout, Size};
use super::{
@@ -500,6 +500,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// contains a reference to memory that was created during its evaluation (i.e., not
// to another static), those inner references only exist in "resolved" form.
if self.tcx.is_foreign_item(def_id) {
+ // This is unreachable in Miri, but can happen in CTFE where we actually *do* support
+ // referencing arbitrary (declared) extern statics.
throw_unsup!(ReadExternStatic(def_id));
}
@@ -670,11 +672,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Can't do this in the match argument, we may get cycle errors since the lock would
// be held throughout the match.
match self.tcx.try_get_global_alloc(id) {
- Some(GlobalAlloc::Static(did)) => {
- assert!(!self.tcx.is_thread_local_static(did));
+ Some(GlobalAlloc::Static(def_id)) => {
+ assert!(self.tcx.is_static(def_id));
+ assert!(!self.tcx.is_thread_local_static(def_id));
// Use size and align of the type.
- let ty = self.tcx.type_of(did);
+ let ty = self.tcx.type_of(def_id);
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
+ assert!(!layout.is_unsized());
(layout.size, layout.align.abi, AllocKind::LiveData)
}
Some(GlobalAlloc::Memory(alloc)) => {
@@ -685,8 +689,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
Some(GlobalAlloc::Function(_)) => bug!("We already checked function pointers above"),
Some(GlobalAlloc::Vtable(..)) => {
- // No data to be accessed here.
- return (Size::ZERO, Align::ONE, AllocKind::Vtable);
+ // No data to be accessed here. But vtables are pointer-aligned.
+ return (Size::ZERO, self.tcx.data_layout.pointer_align.abi, AllocKind::Vtable);
}
// The rest must be dead.
None => {
@@ -726,7 +730,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&self,
ptr: Pointer>,
) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> {
- trace!("get_fn({:?})", ptr);
+ trace!("get_ptr_fn({:?})", ptr);
let (alloc_id, offset, _prov) = self.ptr_get_alloc_id(ptr)?;
if offset.bytes() != 0 {
throw_ub!(InvalidFunctionPointer(Pointer::new(alloc_id, offset)))
@@ -735,6 +739,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
.ok_or_else(|| err_ub!(InvalidFunctionPointer(Pointer::new(alloc_id, offset))).into())
}
+ pub fn get_ptr_vtable(
+ &self,
+ ptr: Pointer >,
+ ) -> InterpResult<'tcx, (Ty<'tcx>, Option>)> {
+ trace!("get_ptr_vtable({:?})", ptr);
+ let (alloc_id, offset, _tag) = self.ptr_get_alloc_id(ptr)?;
+ if offset.bytes() != 0 {
+ throw_ub!(InvalidVtablePointer(Pointer::new(alloc_id, offset)))
+ }
+ match self.tcx.try_get_global_alloc(alloc_id) {
+ Some(GlobalAlloc::Vtable(ty, trait_ref)) => Ok((ty, trait_ref)),
+ _ => throw_ub!(InvalidVtablePointer(Pointer::new(alloc_id, offset))),
+ }
+ }
+
pub fn alloc_mark_immutable(&mut self, id: AllocId) -> InterpResult<'tcx> {
self.get_alloc_raw_mut(id)?.0.mutability = Mutability::Not;
Ok(())
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 4a45d979a79a..c7d8a744f7c0 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -885,28 +885,19 @@ where
}
/// Turn a place with a `dyn Trait` type into a place with the actual dynamic type.
- /// Also return some more information so drop doesn't have to run the same code twice.
pub(super) fn unpack_dyn_trait(
&self,
mplace: &MPlaceTy<'tcx, M::Provenance>,
- ) -> InterpResult<'tcx, (ty::Instance<'tcx>, MPlaceTy<'tcx, M::Provenance>)> {
+ ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
let vtable = self.scalar_to_ptr(mplace.vtable())?; // also sanity checks the type
- let (instance, ty) = self.read_drop_type_from_vtable(vtable)?;
+ let (ty, _) = self.get_ptr_vtable(vtable)?;
let layout = self.layout_of(ty)?;
- // More sanity checks
- if cfg!(debug_assertions) {
- let (size, align) = self.read_size_and_align_from_vtable(vtable)?;
- assert_eq!(size, layout.size);
- // only ABI alignment is preserved
- assert_eq!(align, layout.align.abi);
- }
-
let mplace = MPlaceTy {
mplace: MemPlace { meta: MemPlaceMeta::None, ..**mplace },
layout,
align: layout.align.abi,
};
- Ok((instance, mplace))
+ Ok(mplace)
}
}
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 279ecef08c65..2ae0e1a6f5ac 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -1,5 +1,4 @@
use std::borrow::Cow;
-use std::convert::TryFrom;
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
use rustc_middle::ty::Instance;
@@ -563,7 +562,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ty::Dynamic(..)
));
let vtable = self.scalar_to_ptr(receiver_place.meta.unwrap_meta())?;
- let fn_val = self.get_vtable_slot(vtable, u64::try_from(idx).unwrap())?;
+ let Some(ty::VtblEntry::Method(fn_inst)) = self.get_vtable_entries(vtable)?.get(idx).copied() else {
+ throw_ub_format!(
+ "calling index {idx} of vtable {vtable} but \
+ that vtable is too small or does not have a method at that index"
+ )
+ };
// `*mut receiver_place.layout.ty` is almost the layout that we
// want for args[0]: We have to project to field 0 because we want
@@ -579,7 +583,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
trace!("Patched receiver operand to {:#?}", args[0]);
// recurse with concrete function
self.eval_fn_call(
- fn_val,
+ FnVal::Instance(fn_inst),
(caller_abi, caller_fn_abi),
&args,
with_caller_location,
@@ -606,8 +610,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let (instance, place) = match place.layout.ty.kind() {
ty::Dynamic(..) => {
- // Dropping a trait object.
- self.unpack_dyn_trait(&place)?
+ // Dropping a trait object. Need to find actual drop fn.
+ let place = self.unpack_dyn_trait(&place)?;
+ let instance = ty::Instance::resolve_drop_in_place(*self.tcx, place.layout.ty);
+ (instance, place)
}
_ => (instance, place),
};
diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs
index e4052b617827..bddca2a20ede 100644
--- a/compiler/rustc_const_eval/src/interpret/traits.rs
+++ b/compiler/rustc_const_eval/src/interpret/traits.rs
@@ -1,14 +1,10 @@
-use std::convert::TryFrom;
-
-use rustc_middle::mir::interpret::{alloc_range, InterpResult, Pointer, PointerArithmetic};
-use rustc_middle::ty::{
- self, Ty, TyCtxt, COMMON_VTABLE_ENTRIES_ALIGN, COMMON_VTABLE_ENTRIES_DROPINPLACE,
- COMMON_VTABLE_ENTRIES_SIZE,
-};
+use rustc_middle::mir::interpret::{InterpResult, Pointer};
+use rustc_middle::ty::layout::LayoutOf;
+use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_target::abi::{Align, Size};
use super::util::ensure_monomorphic_enough;
-use super::{FnVal, InterpCx, Machine};
+use super::{InterpCx, Machine};
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Creates a dynamic vtable for the given type and vtable origin. This is used only for
@@ -17,8 +13,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// The `trait_ref` encodes the erased self type. Hence, if we are
/// making an object `Foo` from a value of type `Foo`, then
/// `trait_ref` would map `T: Trait`.
- pub fn get_vtable(
- &mut self,
+ pub fn get_vtable_ptr(
+ &self,
ty: Ty<'tcx>,
poly_trait_ref: Option>,
) -> InterpResult<'tcx, Pointer>> {
@@ -30,114 +26,33 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ensure_monomorphic_enough(*self.tcx, ty)?;
ensure_monomorphic_enough(*self.tcx, poly_trait_ref)?;
- let vtable_allocation = self.tcx.vtable_allocation((ty, poly_trait_ref));
-
- let vtable_ptr = self.global_base_pointer(Pointer::from(vtable_allocation))?;
-
+ let vtable_symbolic_allocation = self.tcx.create_vtable_alloc(ty, poly_trait_ref);
+ let vtable_ptr = self.global_base_pointer(Pointer::from(vtable_symbolic_allocation))?;
Ok(vtable_ptr.into())
}
- /// Resolves the function at the specified slot in the provided
- /// vtable. Currently an index of '3' (`TyCtxt::COMMON_VTABLE_ENTRIES.len()`)
- /// corresponds to the first method declared in the trait of the provided vtable.
- pub fn get_vtable_slot(
+ /// Returns a high-level representation of the entires of the given vtable.
+ pub fn get_vtable_entries(
&self,
vtable: Pointer >,
- idx: u64,
- ) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> {
- let ptr_size = self.pointer_size();
- let vtable_slot = vtable.offset(ptr_size * idx, self)?;
- let vtable_slot = self
- .get_ptr_alloc(vtable_slot, ptr_size, self.tcx.data_layout.pointer_align.abi)?
- .expect("cannot be a ZST");
- let fn_ptr = self.scalar_to_ptr(vtable_slot.read_pointer(Size::ZERO)?.check_init()?)?;
- self.get_ptr_fn(fn_ptr)
+ ) -> InterpResult<'tcx, &'tcx [ty::VtblEntry<'tcx>]> {
+ let (ty, poly_trait_ref) = self.get_ptr_vtable(vtable)?;
+ Ok(if let Some(poly_trait_ref) = poly_trait_ref {
+ let trait_ref = poly_trait_ref.with_self_ty(*self.tcx, ty);
+ let trait_ref = self.tcx.erase_regions(trait_ref);
+ self.tcx.vtable_entries(trait_ref)
+ } else {
+ TyCtxt::COMMON_VTABLE_ENTRIES
+ })
}
- /// Returns the drop fn instance as well as the actual dynamic type.
- pub fn read_drop_type_from_vtable(
- &self,
- vtable: Pointer >,
- ) -> InterpResult<'tcx, (ty::Instance<'tcx>, Ty<'tcx>)> {
- let pointer_size = self.pointer_size();
- // We don't care about the pointee type; we just want a pointer.
- let vtable = self
- .get_ptr_alloc(
- vtable,
- pointer_size * u64::try_from(TyCtxt::COMMON_VTABLE_ENTRIES.len()).unwrap(),
- self.tcx.data_layout.pointer_align.abi,
- )?
- .expect("cannot be a ZST");
- let drop_fn = vtable
- .read_pointer(pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_DROPINPLACE).unwrap())?
- .check_init()?;
- // We *need* an instance here, no other kind of function value, to be able
- // to determine the type.
- let drop_instance = self.get_ptr_fn(self.scalar_to_ptr(drop_fn)?)?.as_instance()?;
- trace!("Found drop fn: {:?}", drop_instance);
- let fn_sig = drop_instance.ty(*self.tcx, self.param_env).fn_sig(*self.tcx);
- let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig);
- // The drop function takes `*mut T` where `T` is the type being dropped, so get that.
- let args = fn_sig.inputs();
- if args.len() != 1 {
- throw_ub!(InvalidVtableDropFn(fn_sig));
- }
- let ty =
- args[0].builtin_deref(true).ok_or_else(|| err_ub!(InvalidVtableDropFn(fn_sig)))?.ty;
- Ok((drop_instance, ty))
- }
-
- pub fn read_size_and_align_from_vtable(
+ pub fn get_vtable_size_and_align(
&self,
vtable: Pointer >,
) -> InterpResult<'tcx, (Size, Align)> {
- let pointer_size = self.pointer_size();
- // We check for `size = 3 * ptr_size`, which covers the drop fn (unused here),
- // the size, and the align (which we read below).
- let vtable = self
- .get_ptr_alloc(
- vtable,
- pointer_size * u64::try_from(TyCtxt::COMMON_VTABLE_ENTRIES.len()).unwrap(),
- self.tcx.data_layout.pointer_align.abi,
- )?
- .expect("cannot be a ZST");
- let size = vtable
- .read_integer(alloc_range(
- pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_SIZE).unwrap(),
- pointer_size,
- ))?
- .check_init()?;
- let size = size.to_machine_usize(self)?;
- let size = Size::from_bytes(size);
- let align = vtable
- .read_integer(alloc_range(
- pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_ALIGN).unwrap(),
- pointer_size,
- ))?
- .check_init()?;
- let align = align.to_machine_usize(self)?;
- let align = Align::from_bytes(align).map_err(|e| err_ub!(InvalidVtableAlignment(e)))?;
-
- if size > self.max_size_of_val() {
- throw_ub!(InvalidVtableSize);
- }
- Ok((size, align))
- }
-
- pub fn read_new_vtable_after_trait_upcasting_from_vtable(
- &self,
- vtable: Pointer >,
- idx: u64,
- ) -> InterpResult<'tcx, Pointer >> {
- let pointer_size = self.pointer_size();
-
- let vtable_slot = vtable.offset(pointer_size * idx, self)?;
- let new_vtable = self
- .get_ptr_alloc(vtable_slot, pointer_size, self.tcx.data_layout.pointer_align.abi)?
- .expect("cannot be a ZST");
-
- let new_vtable = self.scalar_to_ptr(new_vtable.read_pointer(Size::ZERO)?.check_init()?)?;
-
- Ok(new_vtable)
+ let (ty, _trait_ref) = self.get_ptr_vtable(vtable)?;
+ let layout = self.layout_of(ty)?;
+ assert!(!layout.is_unsized(), "there are no vtables for unsized types");
+ Ok((layout.size, layout.align.abi))
}
}
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 569af01c4853..190eb732f9ad 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -313,50 +313,15 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
match tail.kind() {
ty::Dynamic(..) => {
let vtable = self.ecx.scalar_to_ptr(meta.unwrap_meta())?;
- // Direct call to `check_ptr_access_align` checks alignment even on CTFE machines.
- try_validation!(
- self.ecx.check_ptr_access_align(
- vtable,
- 3 * self.ecx.tcx.data_layout.pointer_size, // drop, size, align
- self.ecx.tcx.data_layout.pointer_align.abi,
- CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message
- ),
+ // Make sure it is a genuine vtable pointer.
+ let (_ty, _trait) = try_validation!(
+ self.ecx.get_ptr_vtable(vtable),
self.path,
err_ub!(DanglingIntPointer(..)) |
- err_ub!(PointerUseAfterFree(..)) =>
- { "dangling vtable pointer in wide pointer" },
- err_ub!(AlignmentCheckFailed { .. }) =>
- { "unaligned vtable pointer in wide pointer" },
- err_ub!(PointerOutOfBounds { .. }) =>
- { "too small vtable" },
+ err_ub!(InvalidVtablePointer(..)) =>
+ { "{vtable}" } expected { "a vtable pointer" },
);
- try_validation!(
- self.ecx.read_drop_type_from_vtable(vtable),
- self.path,
- err_ub!(DanglingIntPointer(..)) |
- err_ub!(InvalidFunctionPointer(..)) =>
- { "invalid drop function pointer in vtable (not pointing to a function)" },
- err_ub!(InvalidVtableDropFn(..)) =>
- { "invalid drop function pointer in vtable (function has incompatible signature)" },
- // Stacked Borrows errors can happen here, see https://github.com/rust-lang/miri/issues/2123.
- // (We assume there are no other MachineStop errors possible here.)
- InterpError::MachineStop(_) =>
- { "vtable pointer does not have permission to read drop function pointer" },
- );
- try_validation!(
- self.ecx.read_size_and_align_from_vtable(vtable),
- self.path,
- err_ub!(InvalidVtableSize) =>
- { "invalid vtable: size is bigger than largest supported object" },
- err_ub!(InvalidVtableAlignment(msg)) =>
- { "invalid vtable: alignment {}", msg },
- err_unsup!(ReadPointerAsBytes) => { "invalid size or align in vtable" },
- // Stacked Borrows errors can happen here, see https://github.com/rust-lang/miri/issues/2123.
- // (We assume there are no other MachineStop errors possible here.)
- InterpError::MachineStop(_) =>
- { "vtable pointer does not have permission to read size and alignment" },
- );
- // FIXME: More checks for the vtable.
+ // FIXME: check if the type/trait match what ty::Dynamic says?
}
ty::Slice(..) | ty::Str => {
let _len = try_validation!(
@@ -607,11 +572,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
let _fn = try_validation!(
self.ecx.get_ptr_fn(ptr),
self.path,
- err_ub!(DanglingIntPointer(0, _)) =>
- { "a null function pointer" },
err_ub!(DanglingIntPointer(..)) |
err_ub!(InvalidFunctionPointer(..)) =>
- { "{:x}", value } expected { "a function pointer" },
+ { "{ptr}" } expected { "a function pointer" },
);
// FIXME: Check if the signature matches
} else {
diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs
index 24228feb73e7..aee1f93b1a39 100644
--- a/compiler/rustc_const_eval/src/interpret/visitor.rs
+++ b/compiler/rustc_const_eval/src/interpret/visitor.rs
@@ -425,7 +425,7 @@ macro_rules! make_value_visitor {
// unsized values are never immediate, so we can assert_mem_place
let op = v.to_op_for_read(self.ecx())?;
let dest = op.assert_mem_place();
- let inner_mplace = self.ecx().unpack_dyn_trait(&dest)?.1;
+ let inner_mplace = self.ecx().unpack_dyn_trait(&dest)?;
trace!("walk_value: dyn object layout: {:#?}", inner_mplace.layout);
// recurse with the inner type
return self.visit_field(&v, 0, &$value_trait::from_op(&inner_mplace.into()));
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 68559ae2249f..81d9db98478f 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -1,7 +1,7 @@
use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar};
use crate::mir::interpret::ConstValue;
-use crate::ty::{layout, query::TyCtxtAt, tls, FnSig, Ty, ValTree};
+use crate::ty::{layout, query::TyCtxtAt, tls, Ty, ValTree};
use rustc_data_structures::sync::Lock;
use rustc_errors::{pluralize, struct_span_err, DiagnosticBuilder, ErrorGuaranteed};
@@ -219,7 +219,7 @@ pub struct ScalarSizeMismatch {
}
/// Error information for when the program caused Undefined Behavior.
-pub enum UndefinedBehaviorInfo<'tcx> {
+pub enum UndefinedBehaviorInfo {
/// Free-form case. Only for errors that are never caught!
Ub(String),
/// Unreachable code was executed.
@@ -241,12 +241,6 @@ pub enum UndefinedBehaviorInfo<'tcx> {
PointerArithOverflow,
/// Invalid metadata in a wide pointer (using `str` to avoid allocations).
InvalidMeta(&'static str),
- /// Invalid drop function in vtable.
- InvalidVtableDropFn(FnSig<'tcx>),
- /// Invalid size in a vtable: too large.
- InvalidVtableSize,
- /// Invalid alignment in a vtable: too large, or not a power of 2.
- InvalidVtableAlignment(String),
/// Reading a C string that does not end within its allocation.
UnterminatedCString(Pointer),
/// Dereferencing a dangling pointer after it got freed.
@@ -290,6 +284,8 @@ pub enum UndefinedBehaviorInfo<'tcx> {
InvalidTag(Scalar),
/// Using a pointer-not-to-a-function as function pointer.
InvalidFunctionPointer(Pointer),
+ /// Using a pointer-not-to-a-vtable as vtable pointer.
+ InvalidVtablePointer(Pointer),
/// Using a string that is not valid UTF-8,
InvalidStr(std::str::Utf8Error),
/// Using uninitialized data where it is not allowed.
@@ -302,7 +298,7 @@ pub enum UndefinedBehaviorInfo<'tcx> {
UninhabitedEnumVariantWritten,
}
-impl fmt::Display for UndefinedBehaviorInfo<'_> {
+impl fmt::Display for UndefinedBehaviorInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use UndefinedBehaviorInfo::*;
match self {
@@ -317,14 +313,6 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
RemainderOverflow => write!(f, "overflow in signed remainder (dividing MIN by -1)"),
PointerArithOverflow => write!(f, "overflowing in-bounds pointer arithmetic"),
InvalidMeta(msg) => write!(f, "invalid metadata in wide pointer: {msg}"),
- InvalidVtableDropFn(sig) => write!(
- f,
- "invalid drop function signature: got {sig}, expected exactly one argument which must be a pointer type",
- ),
- InvalidVtableSize => {
- write!(f, "invalid vtable: size is bigger than largest supported object")
- }
- InvalidVtableAlignment(msg) => write!(f, "invalid vtable: alignment {msg}"),
UnterminatedCString(p) => write!(
f,
"reading a null-terminated string starting at {p:?} with no null found before end of allocation",
@@ -378,6 +366,9 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
InvalidFunctionPointer(p) => {
write!(f, "using {p:?} as function pointer but it does not point to a function")
}
+ InvalidVtablePointer(p) => {
+ write!(f, "using {p:?} as vtable pointer but it does not point to a vtable")
+ }
InvalidStr(err) => write!(f, "this string is not valid UTF-8: {err}"),
InvalidUninitBytes(Some((alloc, info))) => write!(
f,
@@ -497,7 +488,7 @@ impl dyn MachineStopType {
pub enum InterpError<'tcx> {
/// The program caused undefined behavior.
- UndefinedBehavior(UndefinedBehaviorInfo<'tcx>),
+ UndefinedBehavior(UndefinedBehaviorInfo),
/// The program did something the interpreter does not support (some of these *might* be UB
/// but the interpreter is not sure).
Unsupported(UnsupportedOpInfo),
diff --git a/src/test/ui/consts/const-eval/const_transmute.rs b/src/test/ui/consts/const-eval/const_transmute.rs
deleted file mode 100644
index 90a454c75a1c..000000000000
--- a/src/test/ui/consts/const-eval/const_transmute.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-// run-pass
-
-#![allow(dead_code)]
-
-#[repr(C)]
-union Transmute {
- t: T,
- u: U,
-}
-
-trait Bar {
- fn bar(&self) -> u32;
-}
-
-struct Foo {
- foo: u32,
- bar: bool,
-}
-
-impl Bar for Foo {
- fn bar(&self) -> u32 {
- self.foo
- }
-}
-
-impl Drop for Foo {
- fn drop(&mut self) {
- assert!(!self.bar);
- self.bar = true;
- println!("dropping Foo");
- }
-}
-
-#[derive(Copy, Clone)]
-struct Fat<'a>(&'a Foo, &'static VTable);
-
-struct VTable {
- drop: Option fn(&'a mut Foo)>,
- size: usize,
- align: usize,
- bar: for<'a> fn(&'a Foo) -> u32,
-}
-
-const FOO: &dyn Bar = &Foo { foo: 128, bar: false };
-const G: Fat = unsafe { Transmute { t: FOO }.u };
-const F: Option fn(&'a mut Foo)> = G.1.drop;
-const H: for<'a> fn(&'a Foo) -> u32 = G.1.bar;
-
-fn main() {
- let mut foo = Foo { foo: 99, bar: false };
- (F.unwrap())(&mut foo);
- std::mem::forget(foo); // already ran the drop impl
- assert_eq!(H(&Foo { foo: 42, bar: false }), 42);
-}
diff --git a/src/test/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr b/src/test/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr
index c6422447a4b7..965256de21a0 100644
--- a/src/test/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr
@@ -2,19 +2,19 @@ error[E0080]: evaluation of constant value failed
--> $DIR/ub-incorrect-vtable.rs:19:14
|
LL | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid vtable: alignment `1000` is not a power of 2
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: evaluation of constant value failed
--> $DIR/ub-incorrect-vtable.rs:24:14
|
LL | unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid vtable: size is bigger than largest supported object
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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-incorrect-vtable.rs:34:1
+ --> $DIR/ub-incorrect-vtable.rs:33:1
|
LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid vtable: alignment `1000` is not a power of 2
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
@@ -22,16 +22,38 @@ LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-incorrect-vtable.rs:39:1
+ --> $DIR/ub-incorrect-vtable.rs:38:1
|
LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid vtable: size is bigger than largest supported object
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼
}
-error: aborting due to 4 previous errors
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:44:1
+ |
+LL | const INVALID_VTABLE_UB: W<&dyn Trait> =
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
+ ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:91:1
+ |
+LL | const G: Wide = unsafe { Transmute { t: FOO }.u };
+ | ^^^^^^^^^^^^^ constructing invalid value at .1: encountered a dangling reference (going beyond the bounds of its allocation)
+ |
+ = 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) {
+ ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼
+ }
+
+error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr b/src/test/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr
index e594ad71b5b4..bd542a7a5f29 100644
--- a/src/test/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr
@@ -2,19 +2,19 @@ error[E0080]: evaluation of constant value failed
--> $DIR/ub-incorrect-vtable.rs:19:14
|
LL | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid vtable: alignment `1000` is not a power of 2
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error[E0080]: evaluation of constant value failed
--> $DIR/ub-incorrect-vtable.rs:24:14
|
LL | unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid vtable: size is bigger than largest supported object
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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-incorrect-vtable.rs:34:1
+ --> $DIR/ub-incorrect-vtable.rs:33:1
|
LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid vtable: alignment `1000` is not a power of 2
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
@@ -22,16 +22,38 @@ LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-incorrect-vtable.rs:39:1
+ --> $DIR/ub-incorrect-vtable.rs:38:1
|
LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid vtable: size is bigger than largest supported object
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼
}
-error: aborting due to 4 previous errors
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:44:1
+ |
+LL | const INVALID_VTABLE_UB: W<&dyn Trait> =
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
+ ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:91:1
+ |
+LL | const G: Wide = unsafe { Transmute { t: FOO }.u };
+ | ^^^^^^^^^^^^^ constructing invalid value at .1: encountered a dangling reference (going beyond the bounds of its allocation)
+ |
+ = 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) {
+ ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼
+ }
+
+error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs b/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs
index 4ec853576c91..4bb30b75bc8e 100644
--- a/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs
+++ b/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs
@@ -18,27 +18,79 @@ trait Trait {}
const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
//~^ ERROR evaluation of constant value failed
-//~| invalid vtable: alignment `1000` is not a power of 2
+//~| does not point to a vtable
const INVALID_VTABLE_SIZE: &dyn Trait =
unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
//~^ ERROR evaluation of constant value failed
-//~| invalid vtable: size is bigger than largest supported object
+//~| does not point to a vtable
#[repr(transparent)]
struct W(T);
-// The drop fn is checked before size/align are, so get ourselves a "sufficiently valid" drop fn
fn drop_me(_: *mut usize) {}
const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), 1usize, 1000usize))) };
//~^^ ERROR it is undefined behavior to use this value
-//~| invalid vtable: alignment `1000` is not a power of 2
+//~| expected a vtable pointer
const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), usize::MAX, 1usize))) };
//~^^ ERROR it is undefined behavior to use this value
-//~| invalid vtable: size is bigger than largest supported object
+//~| expected a vtable pointer
+
+// Even if the vtable has a fn ptr and a reasonable size+align, it still does not work.
+const INVALID_VTABLE_UB: W<&dyn Trait> =
+ unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), 1usize, 1usize))) };
+//~^^ ERROR it is undefined behavior to use this value
+//~| expected a vtable pointer
+
+// Trying to access the data in a vtable does not work, either.
+
+#[derive(Copy, Clone)]
+struct Wide<'a>(&'a Foo, &'static VTable);
+
+struct VTable {
+ drop: Option fn(&'a mut Foo)>,
+ size: usize,
+ align: usize,
+ bar: for<'a> fn(&'a Foo) -> u32,
+}
+
+trait Bar {
+ fn bar(&self) -> u32;
+}
+
+struct Foo {
+ foo: u32,
+ bar: bool,
+}
+
+impl Bar for Foo {
+ fn bar(&self) -> u32 {
+ self.foo
+ }
+}
+
+impl Drop for Foo {
+ fn drop(&mut self) {
+ assert!(!self.bar);
+ self.bar = true;
+ println!("dropping Foo");
+ }
+}
+
+#[repr(C)]
+union Transmute {
+ t: T,
+ u: U,
+}
+
+const FOO: &dyn Bar = &Foo { foo: 128, bar: false };
+const G: Wide = unsafe { Transmute { t: FOO }.u };
+//~^ ERROR it is undefined behavior to use this value
+//~| encountered a dangling reference
+// (it is dangling because vtables do not contain memory that can be dereferenced)
fn main() {}
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
index 2cae35bc4d0e..ae114233c0f7 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
@@ -125,7 +125,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:56:1
|
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
- | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null function pointer
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function 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) {
@@ -147,7 +147,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:60:1
|
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x0000000d, but expected a function pointer
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function 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) {
@@ -158,7 +158,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:62:1
|
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
- | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered pointer to alloc41, but expected a function pointer
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function 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) {
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
index e2cd0e64db80..1b93a869c0dd 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
@@ -125,7 +125,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:56:1
|
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
- | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null function pointer
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function 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) {
@@ -147,7 +147,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:60:1
|
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x000000000000000d, but expected a function pointer
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function 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) {
@@ -158,7 +158,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref-ptr.rs:62:1
|
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
- | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered pointer to alloc41, but expected a function pointer
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function 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) {
diff --git a/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr b/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr
index 43f73f6ec7f2..f7898e55ee2c 100644
--- a/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr
@@ -6,7 +6,7 @@ LL | const BAD_UPVAR: &dyn FnOnce() = &{
|
= 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) {
- ╾─alloc3──╼ ╾─alloc6──╼ │ ╾──╼╾──╼
+ ╾─alloc3──╼ ╾─alloc4──╼ │ ╾──╼╾──╼
}
error: aborting due to previous error
diff --git a/src/test/ui/consts/const-eval/ub-upvars.64bit.stderr b/src/test/ui/consts/const-eval/ub-upvars.64bit.stderr
index 64185a063629..60432380e134 100644
--- a/src/test/ui/consts/const-eval/ub-upvars.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-upvars.64bit.stderr
@@ -6,7 +6,7 @@ LL | const BAD_UPVAR: &dyn FnOnce() = &{
|
= 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) {
- ╾───────alloc3────────╼ ╾───────alloc6────────╼ │ ╾──────╼╾──────╼
+ ╾───────alloc3────────╼ ╾───────alloc4────────╼ │ ╾──────╼╾──────╼
}
error: aborting due to previous error
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
index 2fd98ea322b0..ee27651dca03 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
@@ -209,7 +209,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:117:1
|
LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered too small vtable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
@@ -220,7 +220,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:120:1
|
LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered too small vtable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
@@ -231,51 +231,36 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:123:1
|
LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered dangling vtable pointer in wide pointer
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable 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) {
╾allocN─╼ 04 00 00 00 │ ╾──╼....
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:125:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:125:57
|
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered unaligned vtable pointer in wide 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) {
- ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:127:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:128:57
|
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid drop function pointer in vtable (not pointing to a function)
- |
- = 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) {
- ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:129:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:131:56
|
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid drop function pointer in vtable (not pointing to a function)
- |
- = 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) {
- ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:131:1
+ --> $DIR/ub-wide-ptr.rs:134: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 invalid drop function pointer in vtable (not pointing to a function)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
@@ -283,7 +268,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:135:1
+ --> $DIR/ub-wide-ptr.rs:138:1
|
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..: encountered 0x03, but expected a boolean
@@ -294,10 +279,10 @@ 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:139:1
+ --> $DIR/ub-wide-ptr.rs:142:1
|
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered dangling vtable pointer in wide pointer
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable 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) {
@@ -305,10 +290,10 @@ 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:141:1
+ --> $DIR/ub-wide-ptr.rs:144:1
|
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered too small vtable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable 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) {
@@ -316,16 +301,16 @@ 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:147:5
+ --> $DIR/ub-wide-ptr.rs:150:5
|
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
error[E0080]: could not evaluate static initializer
- --> $DIR/ub-wide-ptr.rs:151:5
+ --> $DIR/ub-wide-ptr.rs:154:5
|
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: allocN has size N, so pointer to 12 bytes starting at offset N is out-of-bounds
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error: aborting due to 32 previous errors
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
index bae249076598..84c323e87b6c 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
@@ -209,7 +209,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:117:1
|
LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered too small vtable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
@@ -220,7 +220,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:120:1
|
LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered too small vtable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
@@ -231,51 +231,36 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:123:1
|
LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered dangling vtable pointer in wide pointer
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable 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) {
╾──────allocN───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-wide-ptr.rs:125:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:125:57
|
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered unaligned vtable pointer in wide 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) {
- ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:127:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:128:57
|
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid drop function pointer in vtable (not pointing to a function)
- |
- = 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) {
- ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:129:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:131:56
|
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid drop function pointer in vtable (not pointing to a function)
- |
- = 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) {
- ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼
- }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:131:1
+ --> $DIR/ub-wide-ptr.rs:134: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 invalid drop function pointer in vtable (not pointing to a function)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable 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) {
@@ -283,7 +268,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:135:1
+ --> $DIR/ub-wide-ptr.rs:138:1
|
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..: encountered 0x03, but expected a boolean
@@ -294,10 +279,10 @@ 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:139:1
+ --> $DIR/ub-wide-ptr.rs:142:1
|
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered dangling vtable pointer in wide pointer
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable 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) {
@@ -305,10 +290,10 @@ 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:141:1
+ --> $DIR/ub-wide-ptr.rs:144:1
|
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered too small vtable
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable 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) {
@@ -316,16 +301,16 @@ 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:147:5
+ --> $DIR/ub-wide-ptr.rs:150:5
|
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
error[E0080]: could not evaluate static initializer
- --> $DIR/ub-wide-ptr.rs:151:5
+ --> $DIR/ub-wide-ptr.rs:154:5
|
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: allocN has size N, so pointer to 24 bytes starting at offset N is out-of-bounds
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
error: aborting due to 32 previous errors
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
index f2e5738f88c9..9e3d349cd7eb 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
@@ -123,11 +123,14 @@ const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8
const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
//~^ ERROR it is undefined behavior to use this value
const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
-//~^ ERROR it is undefined behavior to use this value
+//~^ ERROR evaluation of constant value failed
+//~| does not point to a vtable
const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
-//~^ ERROR it is undefined behavior to use this value
+//~^ ERROR evaluation of constant value failed
+//~| does not point to a vtable
const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
-//~^ ERROR it is undefined behavior to use this value
+//~^ ERROR evaluation of constant value failed
+//~| does not point to a vtable
const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
//~^ ERROR it is undefined behavior to use this value
diff --git a/src/test/ui/consts/issue-79690.64bit.stderr b/src/test/ui/consts/issue-79690.64bit.stderr
index c7aba5553708..b8798a9755fe 100644
--- a/src/test/ui/consts/issue-79690.64bit.stderr
+++ b/src/test/ui/consts/issue-79690.64bit.stderr
@@ -2,11 +2,11 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/issue-79690.rs:30:1
|
LL | const G: Fat = unsafe { Transmute { t: FOO }.u };
- | ^^^^^^^^^^^^ constructing invalid value at .1..size.foo: encountered (potentially part of) a pointer, but expected plain (non-pointer) bytes
+ | ^^^^^^^^^^^^ constructing invalid value at .1: encountered a dangling reference (going beyond the bounds of its allocation)
|
= 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) {
- ╾───────alloc3────────╼ ╾───────alloc6────────╼ │ ╾──────╼╾──────╼
+ ╾───────alloc3────────╼ ╾───────alloc4────────╼ │ ╾──────╼╾──────╼
}
error: aborting due to previous error
diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
index bb8636f1225a..7ea35f70d108 100644
--- a/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
@@ -17,7 +17,7 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
|
= 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) {
- ╾─alloc7──╼ ╾─alloc9──╼ │ ╾──╼╾──╼
+ ╾─alloc7──╼ ╾─alloc8──╼ │ ╾──╼╾──╼
}
error[E0080]: it is undefined behavior to use this value
@@ -28,7 +28,7 @@ LL | const BLUNT: &mut i32 = &mut 42;
|
= 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) {
- ╾─alloc11─╼ │ ╾──╼
+ ╾─alloc10─╼ │ ╾──╼
}
warning: skipping const checks
diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
index f1652da922a5..5ad398930890 100644
--- a/src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
@@ -17,7 +17,7 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
|
= 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) {
- ╾───────alloc7────────╼ ╾───────alloc9────────╼ │ ╾──────╼╾──────╼
+ ╾───────alloc7────────╼ ╾───────alloc8────────╼ │ ╾──────╼╾──────╼
}
error[E0080]: it is undefined behavior to use this value
@@ -28,7 +28,7 @@ LL | const BLUNT: &mut i32 = &mut 42;
|
= 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) {
- ╾───────alloc11───────╼ │ ╾──────╼
+ ╾───────alloc10───────╼ │ ╾──────╼
}
warning: skipping const checks