Auto merge of #127969 - matthiaskrgr:rollup-nhxmwhn, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #112328 (Feat. adding ext that returns change_time)
 - #126199 (Add `isqrt` to `NonZero<uN>`)
 - #127856 (interpret: add sanity check in dyn upcast to double-check what codegen does)
 - #127934 (Improve error when a compiler/library build fails in `checktools.sh`)
 - #127960 (Cleanup dll/exe filename calculations in `run_make_support`)
 - #127963 (Fix display of logo "border")
 - #127967 (Disable run-make/split-debuginfo test for RISC-V 64)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-07-19 16:13:37 +00:00
commit 0cd01aac6a
24 changed files with 341 additions and 330 deletions

View file

@ -401,15 +401,46 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
} }
(ty::Dynamic(data_a, _, ty::Dyn), ty::Dynamic(data_b, _, ty::Dyn)) => { (ty::Dynamic(data_a, _, ty::Dyn), ty::Dynamic(data_b, _, ty::Dyn)) => {
let val = self.read_immediate(src)?; let val = self.read_immediate(src)?;
if data_a.principal() == data_b.principal() { // Take apart the old pointer, and find the dynamic type.
// A NOP cast that doesn't actually change anything, should be allowed even with mismatching vtables.
// (But currently mismatching vtables violate the validity invariant so UB is triggered anyway.)
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_data = old_data.to_pointer(self)?; let old_data = old_data.to_pointer(self)?;
let old_vptr = old_vptr.to_pointer(self)?; let old_vptr = old_vptr.to_pointer(self)?;
let ty = self.get_ptr_vtable_ty(old_vptr, Some(data_a))?; let ty = self.get_ptr_vtable_ty(old_vptr, Some(data_a))?;
// Sanity-check that `supertrait_vtable_slot` in this type's vtable indeed produces
// our destination trait.
if cfg!(debug_assertions) {
let vptr_entry_idx =
self.tcx.supertrait_vtable_slot((src_pointee_ty, dest_pointee_ty));
let vtable_entries = self.vtable_entries(data_a.principal(), ty);
if let Some(entry_idx) = vptr_entry_idx {
let Some(&ty::VtblEntry::TraitVPtr(upcast_trait_ref)) =
vtable_entries.get(entry_idx)
else {
span_bug!(
self.cur_span(),
"invalid vtable entry index in {} -> {} upcast",
src_pointee_ty,
dest_pointee_ty
);
};
let erased_trait_ref = upcast_trait_ref
.map_bound(|r| ty::ExistentialTraitRef::erase_self_ty(*self.tcx, r));
assert!(
data_b
.principal()
.is_some_and(|b| self.eq_in_param_env(erased_trait_ref, b))
);
} else {
// In this case codegen would keep using the old vtable. We don't want to do
// that as it has the wrong trait. The reason codegen can do this is that
// one vtable is a prefix of the other, so we double-check that.
let vtable_entries_b = self.vtable_entries(data_b.principal(), ty);
assert!(&vtable_entries[..vtable_entries_b.len()] == vtable_entries_b);
};
}
// Get the destination trait vtable and return that.
let new_vptr = self.get_vtable_ptr(ty, data_b.principal())?; let new_vptr = self.get_vtable_ptr(ty, data_b.principal())?;
self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest) self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest)
} }

View file

@ -2,11 +2,15 @@ use std::cell::Cell;
use std::{fmt, mem}; use std::{fmt, mem};
use either::{Either, Left, Right}; use either::{Either, Left, Right};
use rustc_infer::infer::at::ToTrace;
use rustc_infer::traits::ObligationCause;
use rustc_trait_selection::traits::ObligationCtxt;
use tracing::{debug, info, info_span, instrument, trace}; use tracing::{debug, info, info_span, instrument, trace};
use rustc_errors::DiagCtxtHandle; use rustc_errors::DiagCtxtHandle;
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::interpret::{ use rustc_middle::mir::interpret::{
CtfeProvenance, ErrorHandled, InvalidMetaKind, ReportedErrorInfo, CtfeProvenance, ErrorHandled, InvalidMetaKind, ReportedErrorInfo,
@ -640,6 +644,32 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
} }
} }
/// Check if the two things are equal in the current param_env, using an infctx to get proper
/// equality checks.
pub(super) fn eq_in_param_env<T>(&self, a: T, b: T) -> bool
where
T: PartialEq + TypeFoldable<TyCtxt<'tcx>> + ToTrace<'tcx>,
{
// Fast path: compare directly.
if a == b {
return true;
}
// Slow path: spin up an inference context to check if these traits are sufficiently equal.
let infcx = self.tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy_with_span(self.cur_span());
// equate the two trait refs after normalization
let a = ocx.normalize(&cause, self.param_env, a);
let b = ocx.normalize(&cause, self.param_env, b);
if ocx.eq(&cause, self.param_env, a, b).is_ok() {
if ocx.select_all_or_error().is_empty() {
// All good.
return true;
}
}
return false;
}
/// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
/// frame which is not `#[track_caller]`. This matches the `caller_location` intrinsic, /// frame which is not `#[track_caller]`. This matches the `caller_location` intrinsic,
/// and is primarily intended for the panic machinery. /// and is primarily intended for the panic machinery.

View file

@ -1,7 +1,6 @@
use std::borrow::Cow; use std::borrow::Cow;
use either::Either; use either::Either;
use rustc_middle::ty::TyCtxt;
use tracing::trace; use tracing::trace;
use rustc_middle::{ use rustc_middle::{
@ -867,7 +866,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}; };
// Obtain the underlying trait we are working on, and the adjusted receiver argument. // Obtain the underlying trait we are working on, and the adjusted receiver argument.
let (dyn_trait, dyn_ty, adjusted_recv) = if let ty::Dynamic(data, _, ty::DynStar) = let (trait_, dyn_ty, adjusted_recv) = if let ty::Dynamic(data, _, ty::DynStar) =
receiver_place.layout.ty.kind() receiver_place.layout.ty.kind()
{ {
let recv = self.unpack_dyn_star(&receiver_place, data)?; let recv = self.unpack_dyn_star(&receiver_place, data)?;
@ -898,20 +897,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
(receiver_trait.principal(), dyn_ty, receiver_place.ptr()) (receiver_trait.principal(), dyn_ty, receiver_place.ptr())
}; };
// Now determine the actual method to call. We can do that in two different ways and // Now determine the actual method to call. Usually we use the easy way of just
// compare them to ensure everything fits. // looking up the method at index `idx`.
let vtable_entries = if let Some(dyn_trait) = dyn_trait { let vtable_entries = self.vtable_entries(trait_, dyn_ty);
let trait_ref = dyn_trait.with_self_ty(*self.tcx, dyn_ty);
let trait_ref = self.tcx.erase_regions(trait_ref);
self.tcx.vtable_entries(trait_ref)
} else {
TyCtxt::COMMON_VTABLE_ENTRIES
};
let Some(ty::VtblEntry::Method(fn_inst)) = vtable_entries.get(idx).copied() else { let Some(ty::VtblEntry::Method(fn_inst)) = vtable_entries.get(idx).copied() else {
// FIXME(fee1-dead) these could be variants of the UB info enum instead of this // FIXME(fee1-dead) these could be variants of the UB info enum instead of this
throw_ub_custom!(fluent::const_eval_dyn_call_not_a_method); throw_ub_custom!(fluent::const_eval_dyn_call_not_a_method);
}; };
trace!("Virtual call dispatches to {fn_inst:#?}"); trace!("Virtual call dispatches to {fn_inst:#?}");
// We can also do the lookup based on `def_id` and `dyn_ty`, and check that that
// produces the same result.
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
let tcx = *self.tcx; let tcx = *self.tcx;

View file

@ -1,10 +1,7 @@
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::interpret::{InterpResult, Pointer}; use rustc_middle::mir::interpret::{InterpResult, Pointer};
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty, TyCtxt, VtblEntry};
use rustc_target::abi::{Align, Size}; use rustc_target::abi::{Align, Size};
use rustc_trait_selection::traits::ObligationCtxt;
use tracing::trace; use tracing::trace;
use super::util::ensure_monomorphic_enough; use super::util::ensure_monomorphic_enough;
@ -47,6 +44,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
Ok((layout.size, layout.align.abi)) Ok((layout.size, layout.align.abi))
} }
pub(super) fn vtable_entries(
&self,
trait_: Option<ty::PolyExistentialTraitRef<'tcx>>,
dyn_ty: Ty<'tcx>,
) -> &'tcx [VtblEntry<'tcx>] {
if let Some(trait_) = trait_ {
let trait_ref = trait_.with_self_ty(*self.tcx, dyn_ty);
let trait_ref = self.tcx.erase_regions(trait_ref);
self.tcx.vtable_entries(trait_ref)
} else {
TyCtxt::COMMON_VTABLE_ENTRIES
}
}
/// Check that the given vtable trait is valid for a pointer/reference/place with the given /// Check that the given vtable trait is valid for a pointer/reference/place with the given
/// expected trait type. /// expected trait type.
pub(super) fn check_vtable_for_type( pub(super) fn check_vtable_for_type(
@ -54,28 +65,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
vtable_trait: Option<ty::PolyExistentialTraitRef<'tcx>>, vtable_trait: Option<ty::PolyExistentialTraitRef<'tcx>>,
expected_trait: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, expected_trait: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// Fast path: if they are equal, it's all fine. let eq = match (expected_trait.principal(), vtable_trait) {
if expected_trait.principal() == vtable_trait { (Some(a), Some(b)) => self.eq_in_param_env(a, b),
return Ok(()); (None, None) => true,
_ => false,
};
if !eq {
throw_ub!(InvalidVTableTrait { expected_trait, vtable_trait });
} }
if let (Some(expected_trait), Some(vtable_trait)) = Ok(())
(expected_trait.principal(), vtable_trait)
{
// Slow path: spin up an inference context to check if these traits are sufficiently equal.
let infcx = self.tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy_with_span(self.cur_span());
// equate the two trait refs after normalization
let expected_trait = ocx.normalize(&cause, self.param_env, expected_trait);
let vtable_trait = ocx.normalize(&cause, self.param_env, vtable_trait);
if ocx.eq(&cause, self.param_env, expected_trait, vtable_trait).is_ok() {
if ocx.select_all_or_error().is_empty() {
// All good.
return Ok(());
}
}
}
throw_ub!(InvalidVTableTrait { expected_trait, vtable_trait });
} }
/// Turn a place with a `dyn Trait` type into a place with the actual dynamic type. /// Turn a place with a `dyn Trait` type into a place with the actual dynamic type.

View file

@ -364,7 +364,9 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe
} }
/// Given a `dyn Subtrait` and `dyn Supertrait` trait object, find the slot of /// Given a `dyn Subtrait` and `dyn Supertrait` trait object, find the slot of
/// // the trait vptr in the subtrait's vtable. /// the trait vptr in the subtrait's vtable.
///
/// A return value of `None` means that the original vtable can be reused.
pub(crate) fn supertrait_vtable_slot<'tcx>( pub(crate) fn supertrait_vtable_slot<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
key: ( key: (
@ -373,8 +375,17 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
), ),
) -> Option<usize> { ) -> Option<usize> {
debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param()); debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param());
let (source, target) = key; let (source, target) = key;
// If the target principal is `None`, we can just return `None`.
let ty::Dynamic(target, _, _) = *target.kind() else {
bug!();
};
let target_principal = tcx
.normalize_erasing_regions(ty::ParamEnv::reveal_all(), target.principal()?)
.with_self_ty(tcx, tcx.types.trait_object_dummy_self);
// Given that we have a target principal, it is a bug for there not to be a source principal.
let ty::Dynamic(source, _, _) = *source.kind() else { let ty::Dynamic(source, _, _) = *source.kind() else {
bug!(); bug!();
}; };
@ -382,13 +393,6 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
.normalize_erasing_regions(ty::ParamEnv::reveal_all(), source.principal().unwrap()) .normalize_erasing_regions(ty::ParamEnv::reveal_all(), source.principal().unwrap())
.with_self_ty(tcx, tcx.types.trait_object_dummy_self); .with_self_ty(tcx, tcx.types.trait_object_dummy_self);
let ty::Dynamic(target, _, _) = *target.kind() else {
bug!();
};
let target_principal = tcx
.normalize_erasing_regions(ty::ParamEnv::reveal_all(), target.principal().unwrap())
.with_self_ty(tcx, tcx.types.trait_object_dummy_self);
let vtable_segment_callback = { let vtable_segment_callback = {
let mut vptr_offset = 0; let mut vptr_offset = 0;
move |segment| { move |segment| {

View file

@ -3,7 +3,6 @@
#![stable(feature = "rust1", since = "1.0.0")] #![stable(feature = "rust1", since = "1.0.0")]
use crate::ascii; use crate::ascii;
use crate::hint;
use crate::intrinsics; use crate::intrinsics;
use crate::mem; use crate::mem;
use crate::str::FromStr; use crate::str::FromStr;

View file

@ -3,6 +3,7 @@
use crate::cmp::Ordering; use crate::cmp::Ordering;
use crate::fmt; use crate::fmt;
use crate::hash::{Hash, Hasher}; use crate::hash::{Hash, Hasher};
use crate::hint;
use crate::intrinsics; use crate::intrinsics;
use crate::marker::{Freeze, StructuralPartialEq}; use crate::marker::{Freeze, StructuralPartialEq};
use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign}; use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign};
@ -604,7 +605,6 @@ macro_rules! nonzero_integer {
} }
nonzero_integer_signedness_dependent_methods! { nonzero_integer_signedness_dependent_methods! {
Self = $Ty,
Primitive = $signedness $Int, Primitive = $signedness $Int,
UnsignedPrimitive = $Uint, UnsignedPrimitive = $Uint,
} }
@ -823,7 +823,7 @@ macro_rules! nonzero_integer {
} }
} }
nonzero_integer_signedness_dependent_impls!($Ty $signedness $Int); nonzero_integer_signedness_dependent_impls!($signedness $Int);
}; };
(Self = $Ty:ident, Primitive = unsigned $Int:ident $(,)?) => { (Self = $Ty:ident, Primitive = unsigned $Int:ident $(,)?) => {
@ -849,7 +849,7 @@ macro_rules! nonzero_integer {
macro_rules! nonzero_integer_signedness_dependent_impls { macro_rules! nonzero_integer_signedness_dependent_impls {
// Impls for unsigned nonzero types only. // Impls for unsigned nonzero types only.
($Ty:ident unsigned $Int:ty) => { (unsigned $Int:ty) => {
#[stable(feature = "nonzero_div", since = "1.51.0")] #[stable(feature = "nonzero_div", since = "1.51.0")]
impl Div<NonZero<$Int>> for $Int { impl Div<NonZero<$Int>> for $Int {
type Output = $Int; type Output = $Int;
@ -897,7 +897,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
} }
}; };
// Impls for signed nonzero types only. // Impls for signed nonzero types only.
($Ty:ident signed $Int:ty) => { (signed $Int:ty) => {
#[stable(feature = "signed_nonzero_neg", since = "1.71.0")] #[stable(feature = "signed_nonzero_neg", since = "1.71.0")]
impl Neg for NonZero<$Int> { impl Neg for NonZero<$Int> {
type Output = Self; type Output = Self;
@ -918,7 +918,6 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
macro_rules! nonzero_integer_signedness_dependent_methods { macro_rules! nonzero_integer_signedness_dependent_methods {
// Associated items for unsigned nonzero types only. // Associated items for unsigned nonzero types only.
( (
Self = $Ty:ident,
Primitive = unsigned $Int:ident, Primitive = unsigned $Int:ident,
UnsignedPrimitive = $Uint:ty, UnsignedPrimitive = $Uint:ty,
) => { ) => {
@ -1224,11 +1223,60 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
intrinsics::ctpop(self.get()) < 2 intrinsics::ctpop(self.get()) < 2
} }
/// Returns the square root of the number, rounded down.
///
/// # Examples
///
/// Basic usage:
/// ```
/// #![feature(isqrt)]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let ten = NonZero::new(10", stringify!($Int), ")?;")]
#[doc = concat!("let three = NonZero::new(3", stringify!($Int), ")?;")]
///
/// assert_eq!(ten.isqrt(), three);
/// # Some(())
/// # }
#[unstable(feature = "isqrt", issue = "116226")]
#[rustc_const_unstable(feature = "isqrt", issue = "116226")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn isqrt(self) -> Self {
// The algorithm is based on the one presented in
// <https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)>
// which cites as source the following C code:
// <https://web.archive.org/web/20120306040058/http://medialab.freaknet.org/martin/src/sqrt/sqrt.c>.
let mut op = self.get();
let mut res = 0;
let mut one = 1 << (self.ilog2() & !1);
while one != 0 {
if op >= res + one {
op -= res + one;
res = (res >> 1) + one;
} else {
res >>= 1;
}
one >>= 2;
}
// SAFETY: The result fits in an integer with half as many bits.
// Inform the optimizer about it.
unsafe { hint::assert_unchecked(res < 1 << (Self::BITS / 2)) };
// SAFETY: The square root of an integer >= 1 is always >= 1.
unsafe { Self::new_unchecked(res) }
}
}; };
// Associated items for signed nonzero types only. // Associated items for signed nonzero types only.
( (
Self = $Ty:ident,
Primitive = signed $Int:ident, Primitive = signed $Int:ident,
UnsignedPrimitive = $Uint:ty, UnsignedPrimitive = $Uint:ty,
) => { ) => {

View file

@ -1226,10 +1226,9 @@ macro_rules! uint_impl {
without modifying the original"] without modifying the original"]
#[inline] #[inline]
pub const fn checked_ilog2(self) -> Option<u32> { pub const fn checked_ilog2(self) -> Option<u32> {
if let Some(x) = NonZero::new(self) { match NonZero::new(self) {
Some(x.ilog2()) Some(x) => Some(x.ilog2()),
} else { None => None,
None
} }
} }
@ -1248,10 +1247,9 @@ macro_rules! uint_impl {
without modifying the original"] without modifying the original"]
#[inline] #[inline]
pub const fn checked_ilog10(self) -> Option<u32> { pub const fn checked_ilog10(self) -> Option<u32> {
if let Some(x) = NonZero::new(self) { match NonZero::new(self) {
Some(x.ilog10()) Some(x) => Some(x.ilog10()),
} else { None => None,
None
} }
} }
@ -2590,37 +2588,10 @@ macro_rules! uint_impl {
without modifying the original"] without modifying the original"]
#[inline] #[inline]
pub const fn isqrt(self) -> Self { pub const fn isqrt(self) -> Self {
if self < 2 { match NonZero::new(self) {
return self; Some(x) => x.isqrt().get(),
None => 0,
} }
// The algorithm is based on the one presented in
// <https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)>
// which cites as source the following C code:
// <https://web.archive.org/web/20120306040058/http://medialab.freaknet.org/martin/src/sqrt/sqrt.c>.
let mut op = self;
let mut res = 0;
let mut one = 1 << (self.ilog2() & !1);
while one != 0 {
if op >= res + one {
op -= res + one;
res = (res >> 1) + one;
} else {
res >>= 1;
}
one >>= 2;
}
// SAFETY: the result is positive and fits in an integer with half as many bits.
// Inform the optimizer about it.
unsafe {
hint::assert_unchecked(0 < res);
hint::assert_unchecked(res < 1 << (Self::BITS / 2));
}
res
} }
/// Performs Euclidean division. /// Performs Euclidean division.

View file

@ -471,6 +471,13 @@ pub trait MetadataExt {
/// `fs::metadata` or `File::metadata`, then this will return `Some`. /// `fs::metadata` or `File::metadata`, then this will return `Some`.
#[unstable(feature = "windows_by_handle", issue = "63010")] #[unstable(feature = "windows_by_handle", issue = "63010")]
fn file_index(&self) -> Option<u64>; fn file_index(&self) -> Option<u64>;
/// Returns the change time, which is the last time file metadata was changed, such as
/// renames, attributes, etc
///
/// This will return `None` if the `Metadata` instance was not created using the `FILE_BASIC_INFO` type.
#[unstable(feature = "windows_change_time", issue = "121478")]
fn change_time(&self) -> Option<u64>;
} }
#[stable(feature = "metadata_ext", since = "1.1.0")] #[stable(feature = "metadata_ext", since = "1.1.0")]
@ -499,6 +506,9 @@ impl MetadataExt for Metadata {
fn file_index(&self) -> Option<u64> { fn file_index(&self) -> Option<u64> {
self.as_inner().file_index() self.as_inner().file_index()
} }
fn change_time(&self) -> Option<u64> {
self.as_inner().changed_u64()
}
} }
/// Windows-specific extensions to [`fs::FileType`]. /// Windows-specific extensions to [`fs::FileType`].

View file

@ -32,6 +32,7 @@ pub struct FileAttr {
creation_time: c::FILETIME, creation_time: c::FILETIME,
last_access_time: c::FILETIME, last_access_time: c::FILETIME,
last_write_time: c::FILETIME, last_write_time: c::FILETIME,
change_time: Option<c::FILETIME>,
file_size: u64, file_size: u64,
reparse_tag: u32, reparse_tag: u32,
volume_serial_number: Option<u32>, volume_serial_number: Option<u32>,
@ -377,6 +378,7 @@ impl File {
creation_time: info.ftCreationTime, creation_time: info.ftCreationTime,
last_access_time: info.ftLastAccessTime, last_access_time: info.ftLastAccessTime,
last_write_time: info.ftLastWriteTime, last_write_time: info.ftLastWriteTime,
change_time: None, // Only available in FILE_BASIC_INFO
file_size: (info.nFileSizeLow as u64) | ((info.nFileSizeHigh as u64) << 32), file_size: (info.nFileSizeLow as u64) | ((info.nFileSizeHigh as u64) << 32),
reparse_tag, reparse_tag,
volume_serial_number: Some(info.dwVolumeSerialNumber), volume_serial_number: Some(info.dwVolumeSerialNumber),
@ -413,6 +415,10 @@ impl File {
dwLowDateTime: info.LastWriteTime as u32, dwLowDateTime: info.LastWriteTime as u32,
dwHighDateTime: (info.LastWriteTime >> 32) as u32, dwHighDateTime: (info.LastWriteTime >> 32) as u32,
}, },
change_time: Some(c::FILETIME {
dhLowDateTime: info.ChangeTime as c::DWORD,
dhHighDateTime: (info.ChangeTime >> 32) as c::DWORD,
}),
file_size: 0, file_size: 0,
reparse_tag: 0, reparse_tag: 0,
volume_serial_number: None, volume_serial_number: None,
@ -957,6 +963,10 @@ impl FileAttr {
to_u64(&self.creation_time) to_u64(&self.creation_time)
} }
pub fn changed_u64(&self) -> Option<u64> {
self.change_time.as_ref().map(|c| to_u64(c))
}
pub fn volume_serial_number(&self) -> Option<u32> { pub fn volume_serial_number(&self) -> Option<u32> {
self.volume_serial_number self.volume_serial_number
} }
@ -976,6 +986,7 @@ impl From<c::WIN32_FIND_DATAW> for FileAttr {
creation_time: wfd.ftCreationTime, creation_time: wfd.ftCreationTime,
last_access_time: wfd.ftLastAccessTime, last_access_time: wfd.ftLastAccessTime,
last_write_time: wfd.ftLastWriteTime, last_write_time: wfd.ftLastWriteTime,
change_time: None,
file_size: ((wfd.nFileSizeHigh as u64) << 32) | (wfd.nFileSizeLow as u64), file_size: ((wfd.nFileSizeHigh as u64) << 32) | (wfd.nFileSizeLow as u64),
reparse_tag: if wfd.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { reparse_tag: if wfd.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
// reserved unless this is a reparse point // reserved unless this is a reparse point

View file

@ -8,6 +8,10 @@ X_PY="$1"
# Try to test the toolstate-tracked tools and store the build/test success in the TOOLSTATE_FILE. # Try to test the toolstate-tracked tools and store the build/test success in the TOOLSTATE_FILE.
# Pre-build the compiler and the library first to output a better error message when the build
# itself fails (see https://github.com/rust-lang/rust/issues/127869 for context).
python3 "$X_PY" build --stage 2 compiler rustdoc
set +e set +e
python3 "$X_PY" test --stage 2 --no-fail-fast \ python3 "$X_PY" test --stage 2 --no-fail-fast \
src/doc/book \ src/doc/book \

View file

@ -675,7 +675,6 @@ ul.block, .block li {
border-top: solid 16px transparent; border-top: solid 16px transparent;
box-sizing: content-box; box-sizing: content-box;
position: relative; position: relative;
background-color: var(--sidebar-background-color);
background-clip: border-box; background-clip: border-box;
z-index: 1; z-index: 1;
} }

View file

@ -59,8 +59,10 @@ impl Baz for i32 {
} }
fn main() { fn main() {
let baz: &dyn Baz = &1; unsafe {
let baz_fake: *const dyn Bar = unsafe { std::mem::transmute(baz) }; let baz: &dyn Baz = &1;
let _err = baz_fake as *const dyn Foo; let baz_fake: *const dyn Bar = std::mem::transmute(baz);
//~^ERROR: using vtable for trait `Baz` but trait `Bar` was expected let _err = baz_fake as *const dyn Foo;
//~^ERROR: using vtable for trait `Baz` but trait `Bar` was expected
}
} }

View file

@ -1,8 +1,8 @@
error: Undefined Behavior: using vtable for trait `Baz` but trait `Bar` was expected error: Undefined Behavior: using vtable for trait `Baz` but trait `Bar` was expected
--> $DIR/dyn-upcast-trait-mismatch.rs:LL:CC --> $DIR/dyn-upcast-trait-mismatch.rs:LL:CC
| |
LL | let _err = baz_fake as *const dyn Foo; LL | let _err = baz_fake as *const dyn Foo;
| ^^^^^^^^ using vtable for trait `Baz` but trait `Bar` was expected | ^^^^^^^^ using vtable for trait `Baz` but trait `Bar` was expected
| |
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

View file

@ -1,7 +1,9 @@
//! A collection of helpers to construct artifact names, such as names of dynamic or static //! A collection of helpers to construct artifact names, such as names of dynamic or static
//! librarys which are target-dependent. //! librarys which are target-dependent.
use crate::targets::{is_darwin, is_msvc, is_windows}; // FIXME(jieyouxu): convert these to return `PathBuf`s instead of strings!
use crate::targets::is_msvc;
/// Construct the static library name based on the target. /// Construct the static library name based on the target.
#[must_use] #[must_use]
@ -31,41 +33,15 @@ pub fn static_lib_name(name: &str) -> String {
/// Construct the dynamic library name based on the target. /// Construct the dynamic library name based on the target.
#[must_use] #[must_use]
pub fn dynamic_lib_name(name: &str) -> String { pub fn dynamic_lib_name(name: &str) -> String {
// See tools.mk (irrelevant lines omitted):
//
// ```makefile
// ifeq ($(UNAME),Darwin)
// DYLIB = $(TMPDIR)/lib$(1).dylib
// else
// ifdef IS_WINDOWS
// DYLIB = $(TMPDIR)/$(1).dll
// else
// DYLIB = $(TMPDIR)/lib$(1).so
// endif
// endif
// ```
assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace"); assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace");
let extension = dynamic_lib_extension(); format!("{}{name}.{}", std::env::consts::DLL_PREFIX, std::env::consts::DLL_EXTENSION)
if is_darwin() {
format!("lib{name}.{extension}")
} else if is_windows() {
format!("{name}.{extension}")
} else {
format!("lib{name}.{extension}")
}
} }
/// Construct the dynamic library extension based on the target. /// Construct the dynamic library extension based on the target.
#[must_use] #[must_use]
pub fn dynamic_lib_extension() -> &'static str { pub fn dynamic_lib_extension() -> &'static str {
if is_darwin() { std::env::consts::DLL_EXTENSION
"dylib"
} else if is_windows() {
"dll"
} else {
"so"
}
} }
/// Construct the name of a rust library (rlib). /// Construct the name of a rust library (rlib).
@ -77,5 +53,5 @@ pub fn rust_lib_name(name: &str) -> String {
/// Construct the binary (executable) name based on the target. /// Construct the binary (executable) name based on the target.
#[must_use] #[must_use]
pub fn bin_name(name: &str) -> String { pub fn bin_name(name: &str) -> String {
if is_windows() { format!("{name}.exe") } else { name.to_string() } format!("{name}{}", std::env::consts::EXE_SUFFIX)
} }

View file

@ -1,4 +1,6 @@
# ignore-cross-compile # ignore-cross-compile
# ignore-riscv64 On this platform only `-Csplit-debuginfo=off` is supported, see #120518
include ../tools.mk include ../tools.mk
all: off packed unpacked all: off packed unpacked

View file

@ -436,30 +436,20 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/raw-bytes.rs:196:1 --> $DIR/raw-bytes.rs:196:62
| |
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
= 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) {
╾ALLOC_ID╼ 00 00 00 00 │ ╾──╼....
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/raw-bytes.rs:198:1 --> $DIR/raw-bytes.rs:199:65
| |
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC27<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC32 as vtable pointer but it does not point to a vtable
|
= 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) {
╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:202:1 --> $DIR/raw-bytes.rs:204:1
| |
LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) };
| ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type [!; 1] | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type [!; 1]
@ -470,7 +460,7 @@ LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:203:1 --> $DIR/raw-bytes.rs:205:1
| |
LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) };
| ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!` | ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!`
@ -481,7 +471,7 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:204:1 --> $DIR/raw-bytes.rs:206:1
| |
LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) };
| ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!` | ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!`
@ -492,7 +482,7 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:208:1 --> $DIR/raw-bytes.rs:210:1
| |
LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) };
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer
@ -503,7 +493,7 @@ LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:211:1 --> $DIR/raw-bytes.rs:213:1
| |
LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) }; LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) };
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer
@ -516,7 +506,7 @@ LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem:
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:214:1 --> $DIR/raw-bytes.rs:216:1
| |
LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean
@ -527,7 +517,7 @@ LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4)
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:218:1 --> $DIR/raw-bytes.rs:220:1
| |
LL | pub static S7: &[u16] = unsafe { LL | pub static S7: &[u16] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[1]: encountered uninitialized memory, but expected an integer | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[1]: encountered uninitialized memory, but expected an integer
@ -538,7 +528,7 @@ LL | pub static S7: &[u16] = unsafe {
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:225:1 --> $DIR/raw-bytes.rs:227:1
| |
LL | pub static R4: &[u8] = unsafe { LL | pub static R4: &[u8] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer
@ -549,7 +539,7 @@ LL | pub static R4: &[u8] = unsafe {
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:230:1 --> $DIR/raw-bytes.rs:232:1
| |
LL | pub static R5: &[u8] = unsafe { LL | pub static R5: &[u8] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer
@ -562,7 +552,7 @@ LL | pub static R5: &[u8] = unsafe {
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:235:1 --> $DIR/raw-bytes.rs:237:1
| |
LL | pub static R6: &[bool] = unsafe { LL | pub static R6: &[bool] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean

View file

@ -436,30 +436,20 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/raw-bytes.rs:196:1 --> $DIR/raw-bytes.rs:196:62
| |
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
= 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) {
╾ALLOC_ID╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/raw-bytes.rs:198:1 --> $DIR/raw-bytes.rs:199:65
| |
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC27<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC32 as vtable pointer but it does not point to a vtable
|
= 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) {
╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:202:1 --> $DIR/raw-bytes.rs:204:1
| |
LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) };
| ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type [!; 1] | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type [!; 1]
@ -470,7 +460,7 @@ LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:203:1 --> $DIR/raw-bytes.rs:205:1
| |
LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) };
| ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!` | ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!`
@ -481,7 +471,7 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:204:1 --> $DIR/raw-bytes.rs:206:1
| |
LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) };
| ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!` | ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!`
@ -492,7 +482,7 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) };
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:208:1 --> $DIR/raw-bytes.rs:210:1
| |
LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) };
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer
@ -503,7 +493,7 @@ LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:211:1 --> $DIR/raw-bytes.rs:213:1
| |
LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) }; LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) };
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer
@ -516,7 +506,7 @@ LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem:
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:214:1 --> $DIR/raw-bytes.rs:216:1
| |
LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean
@ -527,7 +517,7 @@ LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4)
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:218:1 --> $DIR/raw-bytes.rs:220:1
| |
LL | pub static S7: &[u16] = unsafe { LL | pub static S7: &[u16] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[1]: encountered uninitialized memory, but expected an integer | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[1]: encountered uninitialized memory, but expected an integer
@ -538,7 +528,7 @@ LL | pub static S7: &[u16] = unsafe {
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:225:1 --> $DIR/raw-bytes.rs:227:1
| |
LL | pub static R4: &[u8] = unsafe { LL | pub static R4: &[u8] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer
@ -549,7 +539,7 @@ LL | pub static R4: &[u8] = unsafe {
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:230:1 --> $DIR/raw-bytes.rs:232:1
| |
LL | pub static R5: &[u8] = unsafe { LL | pub static R5: &[u8] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer
@ -562,7 +552,7 @@ LL | pub static R5: &[u8] = unsafe {
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/raw-bytes.rs:235:1 --> $DIR/raw-bytes.rs:237:1
| |
LL | pub static R6: &[bool] = unsafe { LL | pub static R6: &[bool] = unsafe {
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean

View file

@ -194,9 +194,11 @@ const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool
//~| expected a boolean //~| expected a boolean
const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| null pointer
const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| vtable
// Uninhabited types // Uninhabited types
const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior

View file

@ -1,8 +1,20 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-incorrect-vtable.rs:18:1 --> $DIR/ub-incorrect-vtable.rs:19:14
| |
LL | const INVALID_VTABLE_ALIGNMENT: &dyn Trait = LL | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC1<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC8 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])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC9 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:33:1
|
LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC1<imm>, 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 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) { = note: the raw bytes of the constant (size: 8, align: 4) {
@ -10,10 +22,10 @@ LL | const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-incorrect-vtable.rs:23:1 --> $DIR/ub-incorrect-vtable.rs:38:1
| |
LL | const INVALID_VTABLE_SIZE: &dyn Trait = LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC3<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC3<imm>, 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 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) { = note: the raw bytes of the constant (size: 8, align: 4) {
@ -21,38 +33,16 @@ LL | const INVALID_VTABLE_SIZE: &dyn Trait =
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-incorrect-vtable.rs:33:1 --> $DIR/ub-incorrect-vtable.rs:44:1
| |
LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> = LL | const INVALID_VTABLE_UB: W<&dyn Trait> =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC5<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC5<imm>, 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 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) { = note: the raw bytes of the constant (size: 8, align: 4) {
╾ALLOC4<imm>╼ ╾ALLOC5<imm>╼ │ ╾──╼╾──╼ ╾ALLOC4<imm>╼ ╾ALLOC5<imm>╼ │ ╾──╼╾──╼
} }
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-incorrect-vtable.rs:38:1
|
LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC7<imm>, 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) {
╾ALLOC6<imm>╼ ╾ALLOC7<imm>╼ │ ╾──╼╾──╼
}
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 ALLOC9<imm>, 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) {
╾ALLOC8<imm>╼ ╾ALLOC9<imm>╼ │ ╾──╼╾──╼
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-incorrect-vtable.rs:91:1 --> $DIR/ub-incorrect-vtable.rs:91:1
| |
@ -61,7 +51,7 @@ LL | const G: Wide = unsafe { Transmute { t: FOO }.u };
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 8, align: 4) { = note: the raw bytes of the constant (size: 8, align: 4) {
╾ALLOC10<imm>╼ ╾ALLOC11╼ │ ╾──╼╾──╼ ╾ALLOC6<imm>╼ ╾ALLOC7╼ │ ╾──╼╾──╼
} }
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View file

@ -1,8 +1,20 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-incorrect-vtable.rs:18:1 --> $DIR/ub-incorrect-vtable.rs:19:14
| |
LL | const INVALID_VTABLE_ALIGNMENT: &dyn Trait = LL | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC1<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC8 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])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC9 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:33:1
|
LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC1<imm>, 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 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) { = note: the raw bytes of the constant (size: 16, align: 8) {
@ -10,10 +22,10 @@ LL | const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-incorrect-vtable.rs:23:1 --> $DIR/ub-incorrect-vtable.rs:38:1
| |
LL | const INVALID_VTABLE_SIZE: &dyn Trait = LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC3<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC3<imm>, 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 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) { = note: the raw bytes of the constant (size: 16, align: 8) {
@ -21,38 +33,16 @@ LL | const INVALID_VTABLE_SIZE: &dyn Trait =
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-incorrect-vtable.rs:33:1 --> $DIR/ub-incorrect-vtable.rs:44:1
| |
LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> = LL | const INVALID_VTABLE_UB: W<&dyn Trait> =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC5<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC5<imm>, 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 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) { = note: the raw bytes of the constant (size: 16, align: 8) {
╾ALLOC4<imm>╼ ╾ALLOC5<imm>╼ │ ╾──────╼╾──────╼ ╾ALLOC4<imm>╼ ╾ALLOC5<imm>╼ │ ╾──────╼╾──────╼
} }
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-incorrect-vtable.rs:38:1
|
LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC7<imm>, 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) {
╾ALLOC6<imm>╼ ╾ALLOC7<imm>╼ │ ╾──────╼╾──────╼
}
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 ALLOC9<imm>, 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) {
╾ALLOC8<imm>╼ ╾ALLOC9<imm>╼ │ ╾──────╼╾──────╼
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-incorrect-vtable.rs:91:1 --> $DIR/ub-incorrect-vtable.rs:91:1
| |
@ -61,7 +51,7 @@ LL | const G: Wide = unsafe { Transmute { t: FOO }.u };
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: 16, align: 8) { = note: the raw bytes of the constant (size: 16, align: 8) {
╾ALLOC10<imm>╼ ╾ALLOC11╼ │ ╾──────╼╾──────╼ ╾ALLOC6<imm>╼ ╾ALLOC7╼ │ ╾──────╼╾──────╼
} }
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View file

@ -17,13 +17,13 @@ trait Trait {}
const INVALID_VTABLE_ALIGNMENT: &dyn Trait = const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) }; unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
//~^^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| expected a vtable pointer //~| vtable
const INVALID_VTABLE_SIZE: &dyn Trait = const INVALID_VTABLE_SIZE: &dyn Trait =
unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) }; unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
//~^^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| expected a vtable pointer //~| vtable
#[repr(transparent)] #[repr(transparent)]
struct W<T>(T); struct W<T>(T);

View file

@ -113,27 +113,27 @@ const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
// bad trait object // bad trait object
const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR it is undefined behavior to use this value
//~| expected a vtable //~| vtable
// bad trait object // bad trait object
const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR it is undefined behavior to use this value
//~| expected a vtable //~| vtable
// bad trait object // bad trait object
const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR it is undefined behavior to use this value
//~| expected a vtable //~| vtable
const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; 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
//~| expected a vtable //~| vtable
const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; 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
//~| expected a vtable //~| vtable
const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; 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
//~| expected a vtable //~| vtable
const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; 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 //~^ ERROR it is undefined behavior to use this value
//~| expected a vtable //~| vtable
// bad data *inside* the trait object // bad data *inside* the trait object
const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
@ -142,21 +142,25 @@ const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool
// # raw trait object // # raw trait object
const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| null pointer
const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
//~^ ERROR it is undefined behavior to use this value //~^ ERROR evaluation of constant value failed
//~| vtable
const RAW_TRAIT_OBJ_CONTENT_INVALID: *const dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) } as *const dyn Trait; // ok because raw const RAW_TRAIT_OBJ_CONTENT_INVALID: *const dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) } as *const dyn Trait; // ok because raw
// Officially blessed way to get the vtable // Officially blessed way to get the vtable
const DYN_METADATA: ptr::DynMetadata<dyn Send> = ptr::metadata::<dyn Send>(ptr::null::<i32>()); const DYN_METADATA: ptr::DynMetadata<dyn Send> = ptr::metadata::<dyn Send>(ptr::null::<i32>());
// Const eval fails for these, so they need to be statics to error.
static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe { static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe {
//~^ ERROR it is undefined behavior to use this value
mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
//~^ ERROR could not evaluate static initializer
//~| null pointer
}; };
static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe { static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe {
//~^ ERROR it is undefined behavior to use this value
mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
//~^ ERROR could not evaluate static initializer
//~| vtable
}; };
fn main() {} fn main() {}

View file

@ -218,44 +218,29 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u
HEX_DUMP HEX_DUMP
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:125:1 --> $DIR/ub-wide-ptr.rs:125:57
| |
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC17<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC20 as vtable pointer but it does not point to a vtable
|
= 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: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:128:1 --> $DIR/ub-wide-ptr.rs:128:57
| |
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC19<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC21 as vtable pointer but it does not point to a vtable
|
= 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: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:131:1 --> $DIR/ub-wide-ptr.rs:131:56
| |
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC21<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC22 as vtable pointer but it does not point to a vtable
|
= 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: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:134: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]))) }; 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 ALLOC23<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC17<imm>, 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 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: $SIZE, align: $ALIGN) { = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
@ -273,49 +258,29 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
HEX_DUMP HEX_DUMP
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:144:1 --> $DIR/ub-wide-ptr.rs:144:62
| |
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
= 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: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:146:1 --> $DIR/ub-wide-ptr.rs:147:65
| |
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC28<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC23 as vtable pointer but it does not point to a vtable
|
= 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: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value error[E0080]: could not evaluate static initializer
--> $DIR/ub-wide-ptr.rs:153:1 --> $DIR/ub-wide-ptr.rs:156:5
| |
LL | static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe { LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
= 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: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value error[E0080]: could not evaluate static initializer
--> $DIR/ub-wide-ptr.rs:157:1 --> $DIR/ub-wide-ptr.rs:161:5
| |
LL | static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe { LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC31<imm>, but expected a vtable pointer | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using ALLOC24 as vtable pointer but it does not point to a vtable
|
= 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: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error: aborting due to 29 previous errors error: aborting due to 29 previous errors