Auto merge of #101183 - Dylan-DPC:rollup-6kewixv, r=Dylan-DPC
Rollup of 9 pull requests Successful merges: - #95376 (Add `vec::Drain{,Filter}::keep_rest`) - #100092 (Fall back when relating two opaques by substs in MIR typeck) - #101019 (Suggest returning closure as `impl Fn`) - #101022 (Erase late bound regions before comparing types in `suggest_dereferences`) - #101101 (interpret: make read-pointer-as-bytes a CTFE-only error with extra information) - #101123 (Remove `register_attr` feature) - #101175 (Don't --bless in pre-push hook) - #101176 (rustdoc: remove unused CSS selectors for `.table-display`) - #101180 (Add another MaybeUninit array test with const) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0631ea5d73
97 changed files with 1397 additions and 1087 deletions
|
@ -430,7 +430,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
|||
let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec();
|
||||
data_ctx.define(bytes.into_boxed_slice());
|
||||
|
||||
for &(offset, alloc_id) in alloc.relocations().iter() {
|
||||
for &(offset, alloc_id) in alloc.provenance().iter() {
|
||||
let addend = {
|
||||
let endianness = tcx.data_layout.endian;
|
||||
let offset = offset.bytes() as usize;
|
||||
|
|
|
@ -186,7 +186,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||
let size = Size::from_bytes(
|
||||
4 * ret_lane_count, /* size_of([u32; ret_lane_count]) */
|
||||
);
|
||||
alloc.inner().get_bytes(fx, alloc_range(offset, size)).unwrap()
|
||||
alloc
|
||||
.inner()
|
||||
.get_bytes_strip_provenance(fx, alloc_range(offset, size))
|
||||
.unwrap()
|
||||
}
|
||||
_ => unreachable!("{:?}", idx_const),
|
||||
};
|
||||
|
|
|
@ -127,7 +127,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> {
|
|||
//
|
||||
// We could remove this hack whenever we decide to drop macOS 10.10 support.
|
||||
if self.tcx.sess.target.options.is_like_osx {
|
||||
// The `inspect` method is okay here because we checked relocations, and
|
||||
// The `inspect` method is okay here because we checked for provenance, and
|
||||
// because we are doing this access to inspect the final interpreter state
|
||||
// (not as part of the interpreter execution).
|
||||
//
|
||||
|
@ -296,17 +296,17 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
|
||||
pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAllocation<'tcx>) -> RValue<'gcc> {
|
||||
let alloc = alloc.inner();
|
||||
let mut llvals = Vec::with_capacity(alloc.relocations().len() + 1);
|
||||
let mut llvals = Vec::with_capacity(alloc.provenance().len() + 1);
|
||||
let dl = cx.data_layout();
|
||||
let pointer_size = dl.pointer_size.bytes() as usize;
|
||||
|
||||
let mut next_offset = 0;
|
||||
for &(offset, alloc_id) in alloc.relocations().iter() {
|
||||
for &(offset, alloc_id) in alloc.provenance().iter() {
|
||||
let offset = offset.bytes();
|
||||
assert_eq!(offset as usize as u64, offset);
|
||||
let offset = offset as usize;
|
||||
if offset > next_offset {
|
||||
// This `inspect` is okay since we have checked that it is not within a relocation, it
|
||||
// This `inspect` is okay since we have checked that it is not within a pointer with provenance, it
|
||||
// is within the bounds of the allocation, and it doesn't affect interpreter execution
|
||||
// (we inspect the result after interpreter execution). Any undef byte is replaced with
|
||||
// some arbitrary byte value.
|
||||
|
@ -319,7 +319,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl
|
|||
read_target_uint( dl.endian,
|
||||
// This `inspect` is okay since it is within the bounds of the allocation, it doesn't
|
||||
// affect interpreter execution (we inspect the result after interpreter execution),
|
||||
// and we properly interpret the relocation as a relocation pointer offset.
|
||||
// and we properly interpret the provenance as a relocation pointer offset.
|
||||
alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
|
||||
)
|
||||
.expect("const_alloc_to_llvm: could not read relocation pointer")
|
||||
|
@ -336,7 +336,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl
|
|||
}
|
||||
if alloc.len() >= next_offset {
|
||||
let range = next_offset..alloc.len();
|
||||
// This `inspect` is okay since we have check that it is after all relocations, it is
|
||||
// This `inspect` is okay since we have check that it is after all provenance, it is
|
||||
// within the bounds of the allocation, and it doesn't affect interpreter execution (we
|
||||
// inspect the result after interpreter execution). Any undef byte is replaced with some
|
||||
// arbitrary byte value.
|
||||
|
|
|
@ -27,12 +27,12 @@ use tracing::debug;
|
|||
|
||||
pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<'_>) -> &'ll Value {
|
||||
let alloc = alloc.inner();
|
||||
let mut llvals = Vec::with_capacity(alloc.relocations().len() + 1);
|
||||
let mut llvals = Vec::with_capacity(alloc.provenance().len() + 1);
|
||||
let dl = cx.data_layout();
|
||||
let pointer_size = dl.pointer_size.bytes() as usize;
|
||||
|
||||
// Note: this function may call `inspect_with_uninit_and_ptr_outside_interpreter`,
|
||||
// so `range` must be within the bounds of `alloc` and not contain or overlap a relocation.
|
||||
// Note: this function may call `inspect_with_uninit_and_ptr_outside_interpreter`, so `range`
|
||||
// must be within the bounds of `alloc` and not contain or overlap a pointer provenance.
|
||||
fn append_chunks_of_init_and_uninit_bytes<'ll, 'a, 'b>(
|
||||
llvals: &mut Vec<&'ll Value>,
|
||||
cx: &'a CodegenCx<'ll, 'b>,
|
||||
|
@ -79,12 +79,12 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
|
|||
}
|
||||
|
||||
let mut next_offset = 0;
|
||||
for &(offset, alloc_id) in alloc.relocations().iter() {
|
||||
for &(offset, alloc_id) in alloc.provenance().iter() {
|
||||
let offset = offset.bytes();
|
||||
assert_eq!(offset as usize as u64, offset);
|
||||
let offset = offset as usize;
|
||||
if offset > next_offset {
|
||||
// This `inspect` is okay since we have checked that it is not within a relocation, it
|
||||
// This `inspect` is okay since we have checked that there is no provenance, it
|
||||
// is within the bounds of the allocation, and it doesn't affect interpreter execution
|
||||
// (we inspect the result after interpreter execution).
|
||||
append_chunks_of_init_and_uninit_bytes(&mut llvals, cx, alloc, next_offset..offset);
|
||||
|
@ -93,7 +93,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
|
|||
dl.endian,
|
||||
// This `inspect` is okay since it is within the bounds of the allocation, it doesn't
|
||||
// affect interpreter execution (we inspect the result after interpreter execution),
|
||||
// and we properly interpret the relocation as a relocation pointer offset.
|
||||
// and we properly interpret the provenance as a relocation pointer offset.
|
||||
alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
|
||||
)
|
||||
.expect("const_alloc_to_llvm: could not read relocation pointer")
|
||||
|
@ -121,7 +121,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
|
|||
}
|
||||
if alloc.len() >= next_offset {
|
||||
let range = next_offset..alloc.len();
|
||||
// This `inspect` is okay since we have check that it is after all relocations, it is
|
||||
// This `inspect` is okay since we have check that it is after all provenance, it is
|
||||
// within the bounds of the allocation, and it doesn't affect interpreter execution (we
|
||||
// inspect the result after interpreter execution).
|
||||
append_chunks_of_init_and_uninit_bytes(&mut llvals, cx, alloc, range);
|
||||
|
@ -479,7 +479,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
|
|||
//
|
||||
// We could remove this hack whenever we decide to drop macOS 10.10 support.
|
||||
if self.tcx.sess.target.is_like_osx {
|
||||
// The `inspect` method is okay here because we checked relocations, and
|
||||
// The `inspect` method is okay here because we checked for provenance, and
|
||||
// because we are doing this access to inspect the final interpreter state
|
||||
// (not as part of the interpreter execution).
|
||||
//
|
||||
|
@ -487,7 +487,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
|
|||
// happens to be zero. Instead, we should only check the value of defined bytes
|
||||
// and set all undefined bytes to zero if this allocation is headed for the
|
||||
// BSS.
|
||||
let all_bytes_are_zero = alloc.relocations().is_empty()
|
||||
let all_bytes_are_zero = alloc.provenance().is_empty()
|
||||
&& alloc
|
||||
.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len())
|
||||
.iter()
|
||||
|
@ -511,9 +511,9 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
|
|||
section.as_str().as_ptr().cast(),
|
||||
section.as_str().len() as c_uint,
|
||||
);
|
||||
assert!(alloc.relocations().is_empty());
|
||||
assert!(alloc.provenance().is_empty());
|
||||
|
||||
// The `inspect` method is okay here because we checked relocations, and
|
||||
// The `inspect` method is okay here because we checked for provenance, and
|
||||
// because we are doing this access to inspect the final interpreter state (not
|
||||
// as part of the interpreter execution).
|
||||
let bytes =
|
||||
|
|
|
@ -10,6 +10,7 @@ use rustc_span::{Span, Symbol};
|
|||
use super::InterpCx;
|
||||
use crate::interpret::{
|
||||
struct_error, ErrorHandled, FrameInfo, InterpError, InterpErrorInfo, Machine, MachineStopType,
|
||||
UnsupportedOpInfo,
|
||||
};
|
||||
|
||||
/// The CTFE machine has some custom error kinds.
|
||||
|
@ -149,6 +150,18 @@ impl<'tcx> ConstEvalErr<'tcx> {
|
|||
if let Some(span_msg) = span_msg {
|
||||
err.span_label(self.span, span_msg);
|
||||
}
|
||||
// Add some more context for select error types.
|
||||
match self.error {
|
||||
InterpError::Unsupported(
|
||||
UnsupportedOpInfo::ReadPointerAsBytes
|
||||
| UnsupportedOpInfo::PartialPointerOverwrite(_)
|
||||
| UnsupportedOpInfo::PartialPointerCopy(_),
|
||||
) => {
|
||||
err.help("this code performed an operation that depends on the underlying bytes representing a pointer");
|
||||
err.help("the absolute address of a pointer is not known at compile-time, so such operations are not supported");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
// Add spans for the stacktrace. Don't print a single-line backtrace though.
|
||||
if self.stacktrace.len() > 1 {
|
||||
// Helper closure to print duplicated lines.
|
||||
|
|
|
@ -2,8 +2,8 @@ use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr};
|
|||
use crate::interpret::eval_nullary_intrinsic;
|
||||
use crate::interpret::{
|
||||
intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId,
|
||||
Immediate, InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking,
|
||||
StackPopCleanup,
|
||||
Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy,
|
||||
RefTracking, StackPopCleanup,
|
||||
};
|
||||
|
||||
use rustc_hir::def::DefKind;
|
||||
|
@ -387,7 +387,9 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
|||
ecx.tcx,
|
||||
"it is undefined behavior to use this value",
|
||||
|diag| {
|
||||
diag.note(NOTE_ON_UNDEFINED_BEHAVIOR_ERROR);
|
||||
if matches!(err.error, InterpError::UndefinedBehavior(_)) {
|
||||
diag.note(NOTE_ON_UNDEFINED_BEHAVIOR_ERROR);
|
||||
}
|
||||
diag.note(&format!(
|
||||
"the raw bytes of the constant ({}",
|
||||
display_allocation(
|
||||
|
|
|
@ -134,7 +134,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval:
|
|||
alloc.mutability = Mutability::Not;
|
||||
};
|
||||
// link the alloc id to the actual allocation
|
||||
leftover_allocations.extend(alloc.relocations().iter().map(|&(_, alloc_id)| alloc_id));
|
||||
leftover_allocations.extend(alloc.provenance().iter().map(|&(_, alloc_id)| alloc_id));
|
||||
let alloc = tcx.intern_const_alloc(alloc);
|
||||
tcx.set_alloc_id_memory(alloc_id, alloc);
|
||||
None
|
||||
|
@ -191,10 +191,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
|
|||
return Ok(true);
|
||||
};
|
||||
|
||||
// If there are no relocations in this allocation, it does not contain references
|
||||
// If there is no provenance in this allocation, it does not contain references
|
||||
// that point to another allocation, and we can avoid the interning walk.
|
||||
if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr, size, align)? {
|
||||
if !alloc.has_relocations() {
|
||||
if !alloc.has_provenance() {
|
||||
return Ok(false);
|
||||
}
|
||||
} else {
|
||||
|
@ -233,8 +233,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
|
|||
}
|
||||
|
||||
fn visit_value(&mut self, mplace: &MPlaceTy<'tcx>) -> InterpResult<'tcx> {
|
||||
// Handle Reference types, as these are the only relocations supported by const eval.
|
||||
// Raw pointers (and boxes) are handled by the `leftover_relocations` logic.
|
||||
// Handle Reference types, as these are the only types with provenance supported by const eval.
|
||||
// Raw pointers (and boxes) are handled by the `leftover_allocations` logic.
|
||||
let tcx = self.ecx.tcx;
|
||||
let ty = mplace.layout.ty;
|
||||
if let ty::Ref(_, referenced_ty, ref_mutability) = *ty.kind() {
|
||||
|
@ -410,7 +410,7 @@ pub fn intern_const_alloc_recursive<
|
|||
// references and a `leftover_allocations` set (where we only have a todo-list here).
|
||||
// So we hand-roll the interning logic here again.
|
||||
match intern_kind {
|
||||
// Statics may contain mutable allocations even behind relocations.
|
||||
// Statics may point to mutable allocations.
|
||||
// Even for immutable statics it would be ok to have mutable allocations behind
|
||||
// raw pointers, e.g. for `static FOO: *const AtomicUsize = &AtomicUsize::new(42)`.
|
||||
InternKind::Static(_) => {}
|
||||
|
@ -441,7 +441,7 @@ pub fn intern_const_alloc_recursive<
|
|||
}
|
||||
let alloc = tcx.intern_const_alloc(alloc);
|
||||
tcx.set_alloc_id_memory(alloc_id, alloc);
|
||||
for &(_, alloc_id) in alloc.inner().relocations().iter() {
|
||||
for &(_, alloc_id) in alloc.inner().provenance().iter() {
|
||||
if leftover_allocations.insert(alloc_id) {
|
||||
todo.push(alloc_id);
|
||||
}
|
||||
|
|
|
@ -687,10 +687,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
let layout = self.layout_of(lhs.layout.ty.builtin_deref(true).unwrap().ty)?;
|
||||
assert!(!layout.is_unsized());
|
||||
|
||||
let lhs = self.read_pointer(lhs)?;
|
||||
let rhs = self.read_pointer(rhs)?;
|
||||
let lhs_bytes = self.read_bytes_ptr(lhs, layout.size)?;
|
||||
let rhs_bytes = self.read_bytes_ptr(rhs, layout.size)?;
|
||||
let get_bytes = |this: &InterpCx<'mir, 'tcx, M>,
|
||||
op: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>,
|
||||
size|
|
||||
-> InterpResult<'tcx, &[u8]> {
|
||||
let ptr = this.read_pointer(op)?;
|
||||
let Some(alloc_ref) = self.get_ptr_alloc(ptr, size, Align::ONE)? else {
|
||||
// zero-sized access
|
||||
return Ok(&[]);
|
||||
};
|
||||
if alloc_ref.has_provenance() {
|
||||
throw_ub_format!("`raw_eq` on bytes with provenance");
|
||||
}
|
||||
alloc_ref.get_bytes_strip_provenance()
|
||||
};
|
||||
|
||||
let lhs_bytes = get_bytes(self, lhs, layout.size)?;
|
||||
let rhs_bytes = get_bytes(self, rhs, layout.size)?;
|
||||
Ok(Scalar::from_bool(lhs_bytes == rhs_bytes))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -315,7 +315,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
/// cache the result. (This relies on `AllocMap::get_or` being able to add the
|
||||
/// owned allocation to the map even when the map is shared.)
|
||||
///
|
||||
/// This must only fail if `alloc` contains relocations.
|
||||
/// This must only fail if `alloc` contains provenance.
|
||||
fn adjust_allocation<'b>(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
id: AllocId,
|
||||
|
|
|
@ -214,7 +214,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
self.allocate_raw_ptr(alloc, kind).unwrap()
|
||||
}
|
||||
|
||||
/// This can fail only of `alloc` contains relocations.
|
||||
/// This can fail only of `alloc` contains provenance.
|
||||
pub fn allocate_raw_ptr(
|
||||
&mut self,
|
||||
alloc: Allocation,
|
||||
|
@ -794,10 +794,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
todo.extend(static_roots);
|
||||
while let Some(id) = todo.pop() {
|
||||
if reachable.insert(id) {
|
||||
// This is a new allocation, add its relocations to `todo`.
|
||||
// This is a new allocation, add the allocation it points to to `todo`.
|
||||
if let Some((_, alloc)) = self.memory.alloc_map.get(id) {
|
||||
todo.extend(
|
||||
alloc.relocations().values().filter_map(|prov| prov.get_alloc_id()),
|
||||
alloc.provenance().values().filter_map(|prov| prov.get_alloc_id()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -833,7 +833,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a,
|
|||
allocs_to_print: &mut VecDeque<AllocId>,
|
||||
alloc: &Allocation<Prov, Extra>,
|
||||
) -> std::fmt::Result {
|
||||
for alloc_id in alloc.relocations().values().filter_map(|prov| prov.get_alloc_id()) {
|
||||
for alloc_id in alloc.provenance().values().filter_map(|prov| prov.get_alloc_id()) {
|
||||
allocs_to_print.push_back(alloc_id);
|
||||
}
|
||||
write!(fmt, "{}", display_allocation(tcx, alloc))
|
||||
|
@ -953,24 +953,25 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRef<'a, 'tcx, Prov, Extra> {
|
|||
}
|
||||
|
||||
/// `range` is relative to this allocation reference, not the base of the allocation.
|
||||
pub fn check_bytes(&self, range: AllocRange) -> InterpResult<'tcx> {
|
||||
pub fn get_bytes_strip_provenance<'b>(&'b self) -> InterpResult<'tcx, &'a [u8]> {
|
||||
Ok(self
|
||||
.alloc
|
||||
.check_bytes(&self.tcx, self.range.subrange(range))
|
||||
.get_bytes_strip_provenance(&self.tcx, self.range)
|
||||
.map_err(|e| e.to_interp_error(self.alloc_id))?)
|
||||
}
|
||||
|
||||
/// Returns whether the allocation has relocations for the entire range of the `AllocRef`.
|
||||
pub(crate) fn has_relocations(&self) -> bool {
|
||||
self.alloc.has_relocations(&self.tcx, self.range)
|
||||
/// Returns whether the allocation has provenance anywhere in the range of the `AllocRef`.
|
||||
pub(crate) fn has_provenance(&self) -> bool {
|
||||
self.alloc.range_has_provenance(&self.tcx, self.range)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
/// Reads the given number of bytes from memory. Returns them as a slice.
|
||||
/// Reads the given number of bytes from memory, and strips their provenance if possible.
|
||||
/// Returns them as a slice.
|
||||
///
|
||||
/// Performs appropriate bounds checks.
|
||||
pub fn read_bytes_ptr(
|
||||
pub fn read_bytes_ptr_strip_provenance(
|
||||
&self,
|
||||
ptr: Pointer<Option<M::Provenance>>,
|
||||
size: Size,
|
||||
|
@ -983,7 +984,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
// (We are staying inside the bounds here so all is good.)
|
||||
Ok(alloc_ref
|
||||
.alloc
|
||||
.get_bytes(&alloc_ref.tcx, alloc_ref.range)
|
||||
.get_bytes_strip_provenance(&alloc_ref.tcx, alloc_ref.range)
|
||||
.map_err(|e| e.to_interp_error(alloc_ref.alloc_id))?)
|
||||
}
|
||||
|
||||
|
@ -1078,17 +1079,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
return Ok(());
|
||||
};
|
||||
|
||||
// This checks relocation edges on the src, which needs to happen before
|
||||
// `prepare_relocation_copy`.
|
||||
let src_bytes = src_alloc
|
||||
.get_bytes_with_uninit_and_ptr(&tcx, src_range)
|
||||
.map_err(|e| e.to_interp_error(src_alloc_id))?
|
||||
.as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
|
||||
// first copy the relocations to a temporary buffer, because
|
||||
// `get_bytes_mut` will clear the relocations, which is correct,
|
||||
// since we don't want to keep any relocations at the target.
|
||||
let relocations =
|
||||
src_alloc.prepare_relocation_copy(self, src_range, dest_offset, num_copies);
|
||||
// Checks provenance edges on the src, which needs to happen before
|
||||
// `prepare_provenance_copy`.
|
||||
if src_alloc.range_has_provenance(&tcx, alloc_range(src_range.start, Size::ZERO)) {
|
||||
throw_unsup!(PartialPointerCopy(Pointer::new(src_alloc_id, src_range.start)));
|
||||
}
|
||||
if src_alloc.range_has_provenance(&tcx, alloc_range(src_range.end(), Size::ZERO)) {
|
||||
throw_unsup!(PartialPointerCopy(Pointer::new(src_alloc_id, src_range.end())));
|
||||
}
|
||||
let src_bytes = src_alloc.get_bytes_unchecked(src_range).as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
|
||||
// first copy the provenance to a temporary buffer, because
|
||||
// `get_bytes_mut` will clear the provenance, which is correct,
|
||||
// since we don't want to keep any provenance at the target.
|
||||
let provenance =
|
||||
src_alloc.prepare_provenance_copy(self, src_range, dest_offset, num_copies);
|
||||
// Prepare a copy of the initialization mask.
|
||||
let compressed = src_alloc.compress_uninit_range(src_range);
|
||||
|
||||
|
@ -1117,7 +1121,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
dest_alloc
|
||||
.write_uninit(&tcx, dest_range)
|
||||
.map_err(|e| e.to_interp_error(dest_alloc_id))?;
|
||||
// We can forget about the relocations, this is all not initialized anyway.
|
||||
// We can forget about the provenance, this is all not initialized anyway.
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -1161,8 +1165,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
alloc_range(dest_offset, size), // just a single copy (i.e., not full `dest_range`)
|
||||
num_copies,
|
||||
);
|
||||
// copy the relocations to the destination
|
||||
dest_alloc.mark_relocation_range(relocations);
|
||||
// copy the provenance to the destination
|
||||
dest_alloc.mark_provenance_range(provenance);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -415,7 +415,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
/// Turn the wide MPlace into a string (must already be dereferenced!)
|
||||
pub fn read_str(&self, mplace: &MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx, &str> {
|
||||
let len = mplace.len(self)?;
|
||||
let bytes = self.read_bytes_ptr(mplace.ptr, Size::from_bytes(len))?;
|
||||
let bytes = self.read_bytes_ptr_strip_provenance(mplace.ptr, Size::from_bytes(len))?;
|
||||
let str = std::str::from_utf8(bytes).map_err(|err| err_ub!(InvalidStr(err)))?;
|
||||
Ok(str)
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//! into a place.
|
||||
//! All high-level functions to write to memory work on places as destinations.
|
||||
|
||||
use std::hash::Hash;
|
||||
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty;
|
||||
|
@ -290,7 +288,7 @@ impl<'tcx, Prov: Provenance> PlaceTy<'tcx, Prov> {
|
|||
// FIXME: Working around https://github.com/rust-lang/rust/issues/54385
|
||||
impl<'mir, 'tcx: 'mir, Prov, M> InterpCx<'mir, 'tcx, M>
|
||||
where
|
||||
Prov: Provenance + Eq + Hash + 'static,
|
||||
Prov: Provenance + 'static,
|
||||
M: Machine<'mir, 'tcx, Provenance = Prov>,
|
||||
{
|
||||
/// Take a value, which represents a (thin or wide) reference, and make it a place.
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
//! but we still need to do bounds checking and adjust the layout. To not duplicate that with MPlaceTy, we actually
|
||||
//! implement the logic on OpTy, and MPlaceTy calls that.
|
||||
|
||||
use std::hash::Hash;
|
||||
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
|
@ -22,7 +20,7 @@ use super::{
|
|||
// FIXME: Working around https://github.com/rust-lang/rust/issues/54385
|
||||
impl<'mir, 'tcx: 'mir, Prov, M> InterpCx<'mir, 'tcx, M>
|
||||
where
|
||||
Prov: Provenance + Eq + Hash + 'static,
|
||||
Prov: Provenance + 'static,
|
||||
M: Machine<'mir, 'tcx, Provenance = Prov>,
|
||||
{
|
||||
//# Field access
|
||||
|
|
|
@ -20,9 +20,11 @@ use rustc_target::abi::{Abi, Scalar as ScalarAbi, Size, VariantIdx, Variants, Wr
|
|||
|
||||
use std::hash::Hash;
|
||||
|
||||
// for the validation errors
|
||||
use super::UndefinedBehaviorInfo::*;
|
||||
use super::{
|
||||
alloc_range, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy,
|
||||
Machine, MemPlaceMeta, OpTy, Scalar, ValueVisitor,
|
||||
CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, Machine,
|
||||
MemPlaceMeta, OpTy, Scalar, ValueVisitor,
|
||||
};
|
||||
|
||||
macro_rules! throw_validation_failure {
|
||||
|
@ -60,6 +62,7 @@ macro_rules! throw_validation_failure {
|
|||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// The patterns must be of type `UndefinedBehaviorInfo`.
|
||||
/// An additional expected parameter can also be added to the failure message:
|
||||
///
|
||||
/// ```
|
||||
|
@ -87,7 +90,7 @@ macro_rules! try_validation {
|
|||
// allocation here as this can only slow down builds that fail anyway.
|
||||
Err(e) => match e.kind() {
|
||||
$(
|
||||
$($p)|+ =>
|
||||
InterpError::UndefinedBehavior($($p)|+) =>
|
||||
throw_validation_failure!(
|
||||
$where,
|
||||
{ $( $what_fmt ),+ } $( expected { $( $expected_fmt ),+ } )?
|
||||
|
@ -313,8 +316,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
Ok(try_validation!(
|
||||
self.ecx.read_immediate(op),
|
||||
self.path,
|
||||
err_unsup!(ReadPointerAsBytes) => { "(potentially part of) a pointer" } expected { "{expected}" },
|
||||
err_ub!(InvalidUninitBytes(None)) => { "uninitialized memory" } expected { "{expected}" }
|
||||
InvalidUninitBytes(None) => { "uninitialized memory" } expected { "{expected}" }
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -339,18 +341,14 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
let (_ty, _trait) = try_validation!(
|
||||
self.ecx.get_ptr_vtable(vtable),
|
||||
self.path,
|
||||
err_ub!(DanglingIntPointer(..)) |
|
||||
err_ub!(InvalidVTablePointer(..)) =>
|
||||
DanglingIntPointer(..) |
|
||||
InvalidVTablePointer(..) =>
|
||||
{ "{vtable}" } expected { "a vtable pointer" },
|
||||
);
|
||||
// FIXME: check if the type/trait match what ty::Dynamic says?
|
||||
}
|
||||
ty::Slice(..) | ty::Str => {
|
||||
let _len = try_validation!(
|
||||
meta.unwrap_meta().to_machine_usize(self.ecx),
|
||||
self.path,
|
||||
err_unsup!(ReadPointerAsBytes) => { "non-integer slice length in wide pointer" },
|
||||
);
|
||||
let _len = meta.unwrap_meta().to_machine_usize(self.ecx)?;
|
||||
// We do not check that `len * elem_size <= isize::MAX`:
|
||||
// that is only required for references, and there it falls out of the
|
||||
// "dereferenceable" check performed by Stacked Borrows.
|
||||
|
@ -380,7 +378,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
let size_and_align = try_validation!(
|
||||
self.ecx.size_and_align_of_mplace(&place),
|
||||
self.path,
|
||||
err_ub!(InvalidMeta(msg)) => { "invalid {} metadata: {}", kind, msg },
|
||||
InvalidMeta(msg) => { "invalid {} metadata: {}", kind, msg },
|
||||
);
|
||||
let (size, align) = size_and_align
|
||||
// for the purpose of validity, consider foreign types to have
|
||||
|
@ -396,21 +394,21 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message
|
||||
),
|
||||
self.path,
|
||||
err_ub!(AlignmentCheckFailed { required, has }) =>
|
||||
AlignmentCheckFailed { required, has } =>
|
||||
{
|
||||
"an unaligned {kind} (required {} byte alignment but found {})",
|
||||
required.bytes(),
|
||||
has.bytes()
|
||||
},
|
||||
err_ub!(DanglingIntPointer(0, _)) =>
|
||||
DanglingIntPointer(0, _) =>
|
||||
{ "a null {kind}" },
|
||||
err_ub!(DanglingIntPointer(i, _)) =>
|
||||
DanglingIntPointer(i, _) =>
|
||||
{ "a dangling {kind} (address {i:#x} is unallocated)" },
|
||||
err_ub!(PointerOutOfBounds { .. }) =>
|
||||
PointerOutOfBounds { .. } =>
|
||||
{ "a dangling {kind} (going beyond the bounds of its allocation)" },
|
||||
// This cannot happen during const-eval (because interning already detects
|
||||
// dangling pointers), but it can happen in Miri.
|
||||
err_ub!(PointerUseAfterFree(..)) =>
|
||||
PointerUseAfterFree(..) =>
|
||||
{ "a dangling {kind} (use-after-free)" },
|
||||
);
|
||||
// Do not allow pointers to uninhabited types.
|
||||
|
@ -498,7 +496,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
try_validation!(
|
||||
value.to_bool(),
|
||||
self.path,
|
||||
err_ub!(InvalidBool(..)) =>
|
||||
InvalidBool(..) =>
|
||||
{ "{:x}", value } expected { "a boolean" },
|
||||
);
|
||||
Ok(true)
|
||||
|
@ -508,7 +506,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
try_validation!(
|
||||
value.to_char(),
|
||||
self.path,
|
||||
err_ub!(InvalidChar(..)) =>
|
||||
InvalidChar(..) =>
|
||||
{ "{:x}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
|
||||
);
|
||||
Ok(true)
|
||||
|
@ -567,8 +565,8 @@ 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(..)) |
|
||||
err_ub!(InvalidFunctionPointer(..)) =>
|
||||
DanglingIntPointer(..) |
|
||||
InvalidFunctionPointer(..) =>
|
||||
{ "{ptr}" } expected { "a function pointer" },
|
||||
);
|
||||
// FIXME: Check if the signature matches
|
||||
|
@ -683,12 +681,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
Ok(try_validation!(
|
||||
this.ecx.read_discriminant(op),
|
||||
this.path,
|
||||
err_ub!(InvalidTag(val)) =>
|
||||
InvalidTag(val) =>
|
||||
{ "{:x}", val } expected { "a valid enum tag" },
|
||||
err_ub!(InvalidUninitBytes(None)) =>
|
||||
InvalidUninitBytes(None) =>
|
||||
{ "uninitialized bytes" } expected { "a valid enum tag" },
|
||||
err_unsup!(ReadPointerAsBytes) =>
|
||||
{ "a pointer" } expected { "a valid enum tag" },
|
||||
)
|
||||
.1)
|
||||
})
|
||||
|
@ -828,10 +824,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
let mplace = op.assert_mem_place(); // strings are unsized and hence never immediate
|
||||
let len = mplace.len(self.ecx)?;
|
||||
try_validation!(
|
||||
self.ecx.read_bytes_ptr(mplace.ptr, Size::from_bytes(len)),
|
||||
self.ecx.read_bytes_ptr_strip_provenance(mplace.ptr, Size::from_bytes(len)),
|
||||
self.path,
|
||||
err_ub!(InvalidUninitBytes(..)) => { "uninitialized data in `str`" },
|
||||
err_unsup!(ReadPointerAsBytes) => { "a pointer in `str`" },
|
||||
InvalidUninitBytes(..) => { "uninitialized data in `str`" },
|
||||
);
|
||||
}
|
||||
ty::Array(tys, ..) | ty::Slice(tys)
|
||||
|
@ -879,9 +874,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
// We also accept uninit, for consistency with the slow path.
|
||||
let alloc = self.ecx.get_ptr_alloc(mplace.ptr, size, mplace.align)?.expect("we already excluded size 0");
|
||||
|
||||
match alloc.check_bytes(alloc_range(Size::ZERO, size)) {
|
||||
match alloc.get_bytes_strip_provenance() {
|
||||
// In the happy case, we needn't check anything else.
|
||||
Ok(()) => {}
|
||||
Ok(_) => {}
|
||||
// Some error happened, try to provide a more detailed description.
|
||||
Err(err) => {
|
||||
// For some errors we might be able to provide extra information.
|
||||
|
@ -899,9 +894,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
|
||||
throw_validation_failure!(self.path, { "uninitialized bytes" })
|
||||
}
|
||||
err_unsup!(ReadPointerAsBytes) => {
|
||||
throw_validation_failure!(self.path, { "a pointer" } expected { "plain (non-pointer) bytes" })
|
||||
}
|
||||
|
||||
// Propagate upwards (that will also check for unexpected errors).
|
||||
_ => return Err(err),
|
||||
|
@ -942,14 +934,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
Ok(()) => Ok(()),
|
||||
// Pass through validation failures.
|
||||
Err(err) if matches!(err.kind(), err_ub!(ValidationFailure { .. })) => Err(err),
|
||||
// Also pass through InvalidProgram, those just indicate that we could not
|
||||
// validate and each caller will know best what to do with them.
|
||||
Err(err) if matches!(err.kind(), InterpError::InvalidProgram(_)) => Err(err),
|
||||
// Avoid other errors as those do not show *where* in the value the issue lies.
|
||||
Err(err) => {
|
||||
// Complain about any other kind of UB error -- those are bad because we'd like to
|
||||
// report them in a way that shows *where* in the value the issue lies.
|
||||
Err(err) if matches!(err.kind(), InterpError::UndefinedBehavior(_)) => {
|
||||
err.print_backtrace();
|
||||
bug!("Unexpected error during validation: {}", err);
|
||||
bug!("Unexpected Undefined Behavior error during validation: {}", err);
|
||||
}
|
||||
// Pass through everything else.
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -481,8 +481,6 @@ declare_features! (
|
|||
(incomplete, raw_dylib, "1.40.0", Some(58713), None),
|
||||
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
|
||||
(active, raw_ref_op, "1.41.0", Some(64490), None),
|
||||
/// Allows using the `#[register_attr]` attribute.
|
||||
(active, register_attr, "1.41.0", Some(66080), None),
|
||||
/// Allows using the `#[register_tool]` attribute.
|
||||
(active, register_tool, "1.41.0", Some(66079), None),
|
||||
/// Allows the `#[repr(i128)]` attribute for enums.
|
||||
|
|
|
@ -458,10 +458,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
),
|
||||
gated!(ffi_pure, Normal, template!(Word), WarnFollowing, experimental!(ffi_pure)),
|
||||
gated!(ffi_const, Normal, template!(Word), WarnFollowing, experimental!(ffi_const)),
|
||||
gated!(
|
||||
register_attr, CrateLevel, template!(List: "attr1, attr2, ..."), DuplicatesOk,
|
||||
experimental!(register_attr),
|
||||
),
|
||||
gated!(
|
||||
register_tool, CrateLevel, template!(List: "tool1, tool2, ..."), DuplicatesOk,
|
||||
experimental!(register_tool),
|
||||
|
|
|
@ -163,6 +163,9 @@ declare_features! (
|
|||
(removed, quad_precision_float, "1.0.0", None, None, None),
|
||||
(removed, quote, "1.33.0", Some(29601), None, None),
|
||||
(removed, reflect, "1.0.0", Some(27749), None, None),
|
||||
/// Allows using the `#[register_attr]` attribute.
|
||||
(removed, register_attr, "CURRENT_RUSTC_VERSION", Some(66080), None,
|
||||
Some("removed in favor of `#![register_tool]`")),
|
||||
/// Allows using the macros:
|
||||
/// + `__diagnostic_used`
|
||||
/// + `__register_diagnostic`
|
||||
|
|
|
@ -45,8 +45,6 @@ pub enum NonMacroAttrKind {
|
|||
/// Single-segment custom attribute registered by a derive macro
|
||||
/// but used before that derive macro was expanded (deprecated).
|
||||
DeriveHelperCompat,
|
||||
/// Single-segment custom attribute registered with `#[register_attr]`.
|
||||
Registered,
|
||||
}
|
||||
|
||||
/// What kind of definition something is; e.g., `mod` vs `struct`.
|
||||
|
@ -564,15 +562,11 @@ impl NonMacroAttrKind {
|
|||
NonMacroAttrKind::DeriveHelper | NonMacroAttrKind::DeriveHelperCompat => {
|
||||
"derive helper attribute"
|
||||
}
|
||||
NonMacroAttrKind::Registered => "explicitly registered attribute",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn article(self) -> &'static str {
|
||||
match self {
|
||||
NonMacroAttrKind::Registered => "an",
|
||||
_ => "a",
|
||||
}
|
||||
"a"
|
||||
}
|
||||
|
||||
/// Users of some attributes cannot mark them as used, so they are considered always used.
|
||||
|
@ -581,7 +575,7 @@ impl NonMacroAttrKind {
|
|||
NonMacroAttrKind::Tool
|
||||
| NonMacroAttrKind::DeriveHelper
|
||||
| NonMacroAttrKind::DeriveHelperCompat => true,
|
||||
NonMacroAttrKind::Builtin(..) | NonMacroAttrKind::Registered => false,
|
||||
NonMacroAttrKind::Builtin(..) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2725,7 +2725,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
|
|||
a: ty::Region<'tcx>,
|
||||
b: ty::Region<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||
if (a.is_var() && b.is_free_or_static()) || (b.is_var() && a.is_free_or_static()) || a == b
|
||||
if (a.is_var() && b.is_free_or_static())
|
||||
|| (b.is_var() && a.is_free_or_static())
|
||||
|| (a.is_var() && b.is_var())
|
||||
|| a == b
|
||||
{
|
||||
Ok(a)
|
||||
} else {
|
||||
|
|
|
@ -396,6 +396,32 @@ where
|
|||
|
||||
generalizer.relate(value, value)
|
||||
}
|
||||
|
||||
fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
|
||||
let mut generalize = |ty, ty_is_expected| {
|
||||
let var = self.infcx.next_ty_var_id_in_universe(
|
||||
TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: self.delegate.span(),
|
||||
},
|
||||
ty::UniverseIndex::ROOT,
|
||||
);
|
||||
if ty_is_expected {
|
||||
self.relate_ty_var((ty, var))
|
||||
} else {
|
||||
self.relate_ty_var((var, ty))
|
||||
}
|
||||
};
|
||||
let (a, b) = match (a.kind(), b.kind()) {
|
||||
(&ty::Opaque(..), _) => (a, generalize(b, false)?),
|
||||
(_, &ty::Opaque(..)) => (generalize(a, true)?, b),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.delegate.register_opaque_type(a, b, true)?;
|
||||
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
|
||||
Ok(a)
|
||||
}
|
||||
}
|
||||
|
||||
/// When we instantiate an inference variable with a value in
|
||||
|
@ -572,32 +598,16 @@ where
|
|||
(&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)),
|
||||
|
||||
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
|
||||
self.infcx.super_combine_tys(self, a, b)
|
||||
infcx.commit_if_ok(|_| infcx.super_combine_tys(self, a, b)).or_else(|err| {
|
||||
self.tcx().sess.delay_span_bug(
|
||||
self.delegate.span(),
|
||||
"failure to relate an opaque to itself should result in an error later on",
|
||||
);
|
||||
if a_def_id.is_local() { self.relate_opaques(a, b) } else { Err(err) }
|
||||
})
|
||||
}
|
||||
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) if did.is_local() => {
|
||||
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
|
||||
let mut generalize = |ty, ty_is_expected| {
|
||||
let var = infcx.next_ty_var_id_in_universe(
|
||||
TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: self.delegate.span(),
|
||||
},
|
||||
ty::UniverseIndex::ROOT,
|
||||
);
|
||||
if ty_is_expected {
|
||||
self.relate_ty_var((ty, var))
|
||||
} else {
|
||||
self.relate_ty_var((var, ty))
|
||||
}
|
||||
};
|
||||
let (a, b) = match (a.kind(), b.kind()) {
|
||||
(&ty::Opaque(..), _) => (a, generalize(b, false)?),
|
||||
(_, &ty::Opaque(..)) => (generalize(a, true)?, b),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.delegate.register_opaque_type(a, b, true)?;
|
||||
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
|
||||
Ok(a)
|
||||
self.relate_opaques(a, b)
|
||||
}
|
||||
|
||||
(&ty::Projection(projection_ty), _)
|
||||
|
|
|
@ -34,11 +34,11 @@ pub struct Allocation<Prov = AllocId, Extra = ()> {
|
|||
/// The actual bytes of the allocation.
|
||||
/// Note that the bytes of a pointer represent the offset of the pointer.
|
||||
bytes: Box<[u8]>,
|
||||
/// Maps from byte addresses to extra data for each pointer.
|
||||
/// Maps from byte addresses to extra provenance data for each pointer.
|
||||
/// Only the first byte of a pointer is inserted into the map; i.e.,
|
||||
/// every entry in this map applies to `pointer_size` consecutive bytes starting
|
||||
/// at the given offset.
|
||||
relocations: Relocations<Prov>,
|
||||
provenance: ProvenanceMap<Prov>,
|
||||
/// Denotes which part of this allocation is initialized.
|
||||
init_mask: InitMask,
|
||||
/// The alignment of the allocation to detect unaligned reads.
|
||||
|
@ -84,7 +84,7 @@ impl hash::Hash for Allocation {
|
|||
}
|
||||
|
||||
// Hash the other fields as usual.
|
||||
self.relocations.hash(state);
|
||||
self.provenance.hash(state);
|
||||
self.init_mask.hash(state);
|
||||
self.align.hash(state);
|
||||
self.mutability.hash(state);
|
||||
|
@ -130,6 +130,8 @@ pub enum AllocError {
|
|||
ReadPointerAsBytes,
|
||||
/// Partially overwriting a pointer.
|
||||
PartialPointerOverwrite(Size),
|
||||
/// Partially copying a pointer.
|
||||
PartialPointerCopy(Size),
|
||||
/// Using uninitialized data where it is not allowed.
|
||||
InvalidUninitBytes(Option<UninitBytesAccess>),
|
||||
}
|
||||
|
@ -152,6 +154,9 @@ impl AllocError {
|
|||
PartialPointerOverwrite(offset) => InterpError::Unsupported(
|
||||
UnsupportedOpInfo::PartialPointerOverwrite(Pointer::new(alloc_id, offset)),
|
||||
),
|
||||
PartialPointerCopy(offset) => InterpError::Unsupported(
|
||||
UnsupportedOpInfo::PartialPointerCopy(Pointer::new(alloc_id, offset)),
|
||||
),
|
||||
InvalidUninitBytes(info) => InterpError::UndefinedBehavior(
|
||||
UndefinedBehaviorInfo::InvalidUninitBytes(info.map(|b| (alloc_id, b))),
|
||||
),
|
||||
|
@ -211,7 +216,7 @@ impl<Prov> Allocation<Prov> {
|
|||
let size = Size::from_bytes(bytes.len());
|
||||
Self {
|
||||
bytes,
|
||||
relocations: Relocations::new(),
|
||||
provenance: ProvenanceMap::new(),
|
||||
init_mask: InitMask::new(size, true),
|
||||
align,
|
||||
mutability,
|
||||
|
@ -246,7 +251,7 @@ impl<Prov> Allocation<Prov> {
|
|||
let bytes = unsafe { bytes.assume_init() };
|
||||
Ok(Allocation {
|
||||
bytes,
|
||||
relocations: Relocations::new(),
|
||||
provenance: ProvenanceMap::new(),
|
||||
init_mask: InitMask::new(size, false),
|
||||
align,
|
||||
mutability: Mutability::Mut,
|
||||
|
@ -266,22 +271,22 @@ impl Allocation {
|
|||
) -> Result<Allocation<Prov, Extra>, Err> {
|
||||
// Compute new pointer provenance, which also adjusts the bytes.
|
||||
let mut bytes = self.bytes;
|
||||
let mut new_relocations = Vec::with_capacity(self.relocations.0.len());
|
||||
let mut new_provenance = Vec::with_capacity(self.provenance.0.len());
|
||||
let ptr_size = cx.data_layout().pointer_size.bytes_usize();
|
||||
let endian = cx.data_layout().endian;
|
||||
for &(offset, alloc_id) in self.relocations.iter() {
|
||||
for &(offset, alloc_id) in self.provenance.iter() {
|
||||
let idx = offset.bytes_usize();
|
||||
let ptr_bytes = &mut bytes[idx..idx + ptr_size];
|
||||
let bits = read_target_uint(endian, ptr_bytes).unwrap();
|
||||
let (ptr_prov, ptr_offset) =
|
||||
adjust_ptr(Pointer::new(alloc_id, Size::from_bytes(bits)))?.into_parts();
|
||||
write_target_uint(endian, ptr_bytes, ptr_offset.bytes().into()).unwrap();
|
||||
new_relocations.push((offset, ptr_prov));
|
||||
new_provenance.push((offset, ptr_prov));
|
||||
}
|
||||
// Create allocation.
|
||||
Ok(Allocation {
|
||||
bytes,
|
||||
relocations: Relocations::from_presorted(new_relocations),
|
||||
provenance: ProvenanceMap::from_presorted(new_provenance),
|
||||
init_mask: self.init_mask,
|
||||
align: self.align,
|
||||
mutability: self.mutability,
|
||||
|
@ -300,8 +305,8 @@ impl<Prov, Extra> Allocation<Prov, Extra> {
|
|||
Size::from_bytes(self.len())
|
||||
}
|
||||
|
||||
/// Looks at a slice which may describe uninitialized bytes or describe a relocation. This differs
|
||||
/// from `get_bytes_with_uninit_and_ptr` in that it does no relocation checks (even on the
|
||||
/// Looks at a slice which may contain uninitialized bytes or provenance. This differs
|
||||
/// from `get_bytes_with_uninit_and_ptr` in that it does no provenance checks (even on the
|
||||
/// edges) at all.
|
||||
/// This must not be used for reads affecting the interpreter execution.
|
||||
pub fn inspect_with_uninit_and_ptr_outside_interpreter(&self, range: Range<usize>) -> &[u8] {
|
||||
|
@ -313,74 +318,47 @@ impl<Prov, Extra> Allocation<Prov, Extra> {
|
|||
&self.init_mask
|
||||
}
|
||||
|
||||
/// Returns the relocation list.
|
||||
pub fn relocations(&self) -> &Relocations<Prov> {
|
||||
&self.relocations
|
||||
/// Returns the provenance map.
|
||||
pub fn provenance(&self) -> &ProvenanceMap<Prov> {
|
||||
&self.provenance
|
||||
}
|
||||
}
|
||||
|
||||
/// Byte accessors.
|
||||
impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
||||
/// This is the entirely abstraction-violating way to just grab the raw bytes without
|
||||
/// caring about relocations. It just deduplicates some code between `read_scalar`
|
||||
/// and `get_bytes_internal`.
|
||||
fn get_bytes_even_more_internal(&self, range: AllocRange) -> &[u8] {
|
||||
&self.bytes[range.start.bytes_usize()..range.end().bytes_usize()]
|
||||
}
|
||||
|
||||
/// The last argument controls whether we error out when there are uninitialized or pointer
|
||||
/// bytes. However, we *always* error when there are relocations overlapping the edges of the
|
||||
/// range.
|
||||
///
|
||||
/// You should never call this, call `get_bytes` or `get_bytes_with_uninit_and_ptr` instead,
|
||||
/// caring about provenance or initialization.
|
||||
///
|
||||
/// This function also guarantees that the resulting pointer will remain stable
|
||||
/// even when new allocations are pushed to the `HashMap`. `mem_copy_repeatedly` relies
|
||||
/// on that.
|
||||
///
|
||||
/// It is the caller's responsibility to check bounds and alignment beforehand.
|
||||
fn get_bytes_internal(
|
||||
&self,
|
||||
cx: &impl HasDataLayout,
|
||||
range: AllocRange,
|
||||
check_init_and_ptr: bool,
|
||||
) -> AllocResult<&[u8]> {
|
||||
if check_init_and_ptr {
|
||||
self.check_init(range)?;
|
||||
self.check_relocations(cx, range)?;
|
||||
} else {
|
||||
// We still don't want relocations on the *edges*.
|
||||
self.check_relocation_edges(cx, range)?;
|
||||
}
|
||||
|
||||
Ok(self.get_bytes_even_more_internal(range))
|
||||
#[inline]
|
||||
pub fn get_bytes_unchecked(&self, range: AllocRange) -> &[u8] {
|
||||
&self.bytes[range.start.bytes_usize()..range.end().bytes_usize()]
|
||||
}
|
||||
|
||||
/// Checks that these bytes are initialized and not pointer bytes, and then return them
|
||||
/// as a slice.
|
||||
/// Checks that these bytes are initialized, and then strip provenance (if possible) and return
|
||||
/// them.
|
||||
///
|
||||
/// It is the caller's responsibility to check bounds and alignment beforehand.
|
||||
/// Most likely, you want to use the `PlaceTy` and `OperandTy`-based methods
|
||||
/// on `InterpCx` instead.
|
||||
#[inline]
|
||||
pub fn get_bytes(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult<&[u8]> {
|
||||
self.get_bytes_internal(cx, range, true)
|
||||
}
|
||||
|
||||
/// It is the caller's responsibility to handle uninitialized and pointer bytes.
|
||||
/// However, this still checks that there are no relocations on the *edges*.
|
||||
///
|
||||
/// It is the caller's responsibility to check bounds and alignment beforehand.
|
||||
#[inline]
|
||||
pub fn get_bytes_with_uninit_and_ptr(
|
||||
pub fn get_bytes_strip_provenance(
|
||||
&self,
|
||||
cx: &impl HasDataLayout,
|
||||
range: AllocRange,
|
||||
) -> AllocResult<&[u8]> {
|
||||
self.get_bytes_internal(cx, range, false)
|
||||
self.check_init(range)?;
|
||||
if !Prov::OFFSET_IS_ADDR {
|
||||
if self.range_has_provenance(cx, range) {
|
||||
return Err(AllocError::ReadPointerAsBytes);
|
||||
}
|
||||
}
|
||||
Ok(self.get_bytes_unchecked(range))
|
||||
}
|
||||
|
||||
/// Just calling this already marks everything as defined and removes relocations,
|
||||
/// Just calling this already marks everything as defined and removes provenance,
|
||||
/// so be sure to actually put data there!
|
||||
///
|
||||
/// It is the caller's responsibility to check bounds and alignment beforehand.
|
||||
|
@ -392,7 +370,7 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
|||
range: AllocRange,
|
||||
) -> AllocResult<&mut [u8]> {
|
||||
self.mark_init(range, true);
|
||||
self.clear_relocations(cx, range)?;
|
||||
self.clear_provenance(cx, range)?;
|
||||
|
||||
Ok(&mut self.bytes[range.start.bytes_usize()..range.end().bytes_usize()])
|
||||
}
|
||||
|
@ -404,7 +382,7 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
|||
range: AllocRange,
|
||||
) -> AllocResult<*mut [u8]> {
|
||||
self.mark_init(range, true);
|
||||
self.clear_relocations(cx, range)?;
|
||||
self.clear_provenance(cx, range)?;
|
||||
|
||||
assert!(range.end().bytes_usize() <= self.bytes.len()); // need to do our own bounds-check
|
||||
let begin_ptr = self.bytes.as_mut_ptr().wrapping_add(range.start.bytes_usize());
|
||||
|
@ -415,13 +393,6 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
|||
|
||||
/// Reading and writing.
|
||||
impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
||||
/// Validates that this memory range is initiailized and contains no relocations.
|
||||
pub fn check_bytes(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult {
|
||||
// This implicitly does all the checking we are asking for.
|
||||
self.get_bytes(cx, range)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Reads a *non-ZST* scalar.
|
||||
///
|
||||
/// If `read_provenance` is `true`, this will also read provenance; otherwise (if the machine
|
||||
|
@ -438,43 +409,53 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
|||
range: AllocRange,
|
||||
read_provenance: bool,
|
||||
) -> AllocResult<Scalar<Prov>> {
|
||||
if read_provenance {
|
||||
assert_eq!(range.size, cx.data_layout().pointer_size);
|
||||
}
|
||||
|
||||
// First and foremost, if anything is uninit, bail.
|
||||
if self.is_init(range).is_err() {
|
||||
return Err(AllocError::InvalidUninitBytes(None));
|
||||
}
|
||||
|
||||
// If we are doing a pointer read, and there is a relocation exactly where we
|
||||
// are reading, then we can put data and relocation back together and return that.
|
||||
if read_provenance && let Some(&prov) = self.relocations.get(&range.start) {
|
||||
// We already checked init and relocations, so we can use this function.
|
||||
let bytes = self.get_bytes_even_more_internal(range);
|
||||
let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
|
||||
let ptr = Pointer::new(prov, Size::from_bytes(bits));
|
||||
return Ok(Scalar::from_pointer(ptr, cx));
|
||||
}
|
||||
|
||||
// If we are *not* reading a pointer, and we can just ignore relocations,
|
||||
// then do exactly that.
|
||||
if !read_provenance && Prov::OFFSET_IS_ADDR {
|
||||
// We just strip provenance.
|
||||
let bytes = self.get_bytes_even_more_internal(range);
|
||||
let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
|
||||
return Ok(Scalar::from_uint(bits, range.size));
|
||||
}
|
||||
|
||||
// It's complicated. Better make sure there is no provenance anywhere.
|
||||
// FIXME: If !OFFSET_IS_ADDR, this is the best we can do. But if OFFSET_IS_ADDR, then
|
||||
// `read_pointer` is true and we ideally would distinguish the following two cases:
|
||||
// - The entire `range` is covered by 2 relocations for the same provenance.
|
||||
// Then we should return a pointer with that provenance.
|
||||
// - The range has inhomogeneous provenance. Then we should return just the
|
||||
// underlying bits.
|
||||
let bytes = self.get_bytes(cx, range)?;
|
||||
// Get the integer part of the result. We HAVE TO check provenance before returning this!
|
||||
let bytes = self.get_bytes_unchecked(range);
|
||||
let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
|
||||
|
||||
if read_provenance {
|
||||
assert_eq!(range.size, cx.data_layout().pointer_size);
|
||||
|
||||
// When reading data with provenance, the easy case is finding provenance exactly where we
|
||||
// are reading, then we can put data and provenance back together and return that.
|
||||
if let Some(&prov) = self.provenance.get(&range.start) {
|
||||
// Now we can return the bits, with their appropriate provenance.
|
||||
let ptr = Pointer::new(prov, Size::from_bytes(bits));
|
||||
return Ok(Scalar::from_pointer(ptr, cx));
|
||||
}
|
||||
|
||||
// If we can work on pointers byte-wise, join the byte-wise provenances.
|
||||
if Prov::OFFSET_IS_ADDR {
|
||||
let mut prov = self.offset_get_provenance(cx, range.start);
|
||||
for offset in 1..range.size.bytes() {
|
||||
let this_prov =
|
||||
self.offset_get_provenance(cx, range.start + Size::from_bytes(offset));
|
||||
prov = Prov::join(prov, this_prov);
|
||||
}
|
||||
// Now use this provenance.
|
||||
let ptr = Pointer::new(prov, Size::from_bytes(bits));
|
||||
return Ok(Scalar::from_maybe_pointer(ptr, cx));
|
||||
}
|
||||
} else {
|
||||
// We are *not* reading a pointer.
|
||||
// If we can just ignore provenance, do exactly that.
|
||||
if Prov::OFFSET_IS_ADDR {
|
||||
// We just strip provenance.
|
||||
return Ok(Scalar::from_uint(bits, range.size));
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback path for when we cannot treat provenance bytewise or ignore it.
|
||||
assert!(!Prov::OFFSET_IS_ADDR);
|
||||
if self.range_has_provenance(cx, range) {
|
||||
return Err(AllocError::ReadPointerAsBytes);
|
||||
}
|
||||
// There is no provenance, we can just return the bits.
|
||||
Ok(Scalar::from_uint(bits, range.size))
|
||||
}
|
||||
|
||||
|
@ -508,9 +489,9 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
|||
let dst = self.get_bytes_mut(cx, range)?;
|
||||
write_target_uint(endian, dst, bytes).unwrap();
|
||||
|
||||
// See if we have to also write a relocation.
|
||||
// See if we have to also store some provenance.
|
||||
if let Some(provenance) = provenance {
|
||||
self.relocations.0.insert(range.start, provenance);
|
||||
self.provenance.0.insert(range.start, provenance);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -519,64 +500,65 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> {
|
|||
/// Write "uninit" to the given memory range.
|
||||
pub fn write_uninit(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult {
|
||||
self.mark_init(range, false);
|
||||
self.clear_relocations(cx, range)?;
|
||||
self.clear_provenance(cx, range)?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
/// Relocations.
|
||||
/// Provenance.
|
||||
impl<Prov: Copy, Extra> Allocation<Prov, Extra> {
|
||||
/// Returns all relocations overlapping with the given pointer-offset pair.
|
||||
fn get_relocations(&self, cx: &impl HasDataLayout, range: AllocRange) -> &[(Size, Prov)] {
|
||||
/// Returns all provenance overlapping with the given pointer-offset pair.
|
||||
fn range_get_provenance(&self, cx: &impl HasDataLayout, range: AllocRange) -> &[(Size, Prov)] {
|
||||
// We have to go back `pointer_size - 1` bytes, as that one would still overlap with
|
||||
// the beginning of this range.
|
||||
let start = range.start.bytes().saturating_sub(cx.data_layout().pointer_size.bytes() - 1);
|
||||
self.relocations.range(Size::from_bytes(start)..range.end())
|
||||
self.provenance.range(Size::from_bytes(start)..range.end())
|
||||
}
|
||||
|
||||
/// Returns whether this allocation has relocations overlapping with the given range.
|
||||
/// Get the provenance of a single byte.
|
||||
fn offset_get_provenance(&self, cx: &impl HasDataLayout, offset: Size) -> Option<Prov> {
|
||||
let prov = self.range_get_provenance(cx, alloc_range(offset, Size::from_bytes(1)));
|
||||
assert!(prov.len() <= 1);
|
||||
prov.first().map(|(_offset, prov)| *prov)
|
||||
}
|
||||
|
||||
/// Returns whether this allocation has progrnance overlapping with the given range.
|
||||
///
|
||||
/// Note: this function exists to allow `get_relocations` to be private, in order to somewhat
|
||||
/// limit access to relocations outside of the `Allocation` abstraction.
|
||||
/// Note: this function exists to allow `range_get_provenance` to be private, in order to somewhat
|
||||
/// limit access to provenance outside of the `Allocation` abstraction.
|
||||
///
|
||||
pub fn has_relocations(&self, cx: &impl HasDataLayout, range: AllocRange) -> bool {
|
||||
!self.get_relocations(cx, range).is_empty()
|
||||
pub fn range_has_provenance(&self, cx: &impl HasDataLayout, range: AllocRange) -> bool {
|
||||
!self.range_get_provenance(cx, range).is_empty()
|
||||
}
|
||||
|
||||
/// Checks that there are no relocations overlapping with the given range.
|
||||
#[inline(always)]
|
||||
fn check_relocations(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult {
|
||||
if self.has_relocations(cx, range) { Err(AllocError::ReadPointerAsBytes) } else { Ok(()) }
|
||||
}
|
||||
|
||||
/// Removes all relocations inside the given range.
|
||||
/// If there are relocations overlapping with the edges, they
|
||||
/// Removes all provenance inside the given range.
|
||||
/// If there is provenance overlapping with the edges, it
|
||||
/// are removed as well *and* the bytes they cover are marked as
|
||||
/// uninitialized. This is a somewhat odd "spooky action at a distance",
|
||||
/// but it allows strictly more code to run than if we would just error
|
||||
/// immediately in that case.
|
||||
fn clear_relocations(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult
|
||||
fn clear_provenance(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult
|
||||
where
|
||||
Prov: Provenance,
|
||||
{
|
||||
// Find the start and end of the given range and its outermost relocations.
|
||||
// Find the start and end of the given range and its outermost provenance.
|
||||
let (first, last) = {
|
||||
// Find all relocations overlapping the given range.
|
||||
let relocations = self.get_relocations(cx, range);
|
||||
if relocations.is_empty() {
|
||||
// Find all provenance overlapping the given range.
|
||||
let provenance = self.range_get_provenance(cx, range);
|
||||
if provenance.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
(
|
||||
relocations.first().unwrap().0,
|
||||
relocations.last().unwrap().0 + cx.data_layout().pointer_size,
|
||||
provenance.first().unwrap().0,
|
||||
provenance.last().unwrap().0 + cx.data_layout().pointer_size,
|
||||
)
|
||||
};
|
||||
let start = range.start;
|
||||
let end = range.end();
|
||||
|
||||
// We need to handle clearing the relocations from parts of a pointer.
|
||||
// FIXME: Miri should preserve partial relocations; see
|
||||
// We need to handle clearing the provenance from parts of a pointer.
|
||||
// FIXME: Miri should preserve partial provenance; see
|
||||
// https://github.com/rust-lang/miri/issues/2181.
|
||||
if first < start {
|
||||
if Prov::ERR_ON_PARTIAL_PTR_OVERWRITE {
|
||||
|
@ -599,41 +581,32 @@ impl<Prov: Copy, Extra> Allocation<Prov, Extra> {
|
|||
self.init_mask.set_range(end, last, false);
|
||||
}
|
||||
|
||||
// Forget all the relocations.
|
||||
// Since relocations do not overlap, we know that removing until `last` (exclusive) is fine,
|
||||
// i.e., this will not remove any other relocations just after the ones we care about.
|
||||
self.relocations.0.remove_range(first..last);
|
||||
// Forget all the provenance.
|
||||
// Since provenance do not overlap, we know that removing until `last` (exclusive) is fine,
|
||||
// i.e., this will not remove any other provenance just after the ones we care about.
|
||||
self.provenance.0.remove_range(first..last);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if there are relocations overlapping with the edges of the
|
||||
/// given memory range.
|
||||
#[inline]
|
||||
fn check_relocation_edges(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult {
|
||||
self.check_relocations(cx, alloc_range(range.start, Size::ZERO))?;
|
||||
self.check_relocations(cx, alloc_range(range.end(), Size::ZERO))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// "Relocations" stores the provenance information of pointers stored in memory.
|
||||
/// Stores the provenance information of pointers stored in memory.
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
|
||||
pub struct Relocations<Prov = AllocId>(SortedMap<Size, Prov>);
|
||||
pub struct ProvenanceMap<Prov = AllocId>(SortedMap<Size, Prov>);
|
||||
|
||||
impl<Prov> Relocations<Prov> {
|
||||
impl<Prov> ProvenanceMap<Prov> {
|
||||
pub fn new() -> Self {
|
||||
Relocations(SortedMap::new())
|
||||
ProvenanceMap(SortedMap::new())
|
||||
}
|
||||
|
||||
// The caller must guarantee that the given relocations are already sorted
|
||||
// The caller must guarantee that the given provenance list is already sorted
|
||||
// by address and contain no duplicates.
|
||||
pub fn from_presorted(r: Vec<(Size, Prov)>) -> Self {
|
||||
Relocations(SortedMap::from_presorted_elements(r))
|
||||
ProvenanceMap(SortedMap::from_presorted_elements(r))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Prov> Deref for Relocations<Prov> {
|
||||
impl<Prov> Deref for ProvenanceMap<Prov> {
|
||||
type Target = SortedMap<Size, Prov>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
@ -641,36 +614,36 @@ impl<Prov> Deref for Relocations<Prov> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A partial, owned list of relocations to transfer into another allocation.
|
||||
/// A partial, owned list of provenance to transfer into another allocation.
|
||||
///
|
||||
/// Offsets are already adjusted to the destination allocation.
|
||||
pub struct AllocationRelocations<Prov> {
|
||||
dest_relocations: Vec<(Size, Prov)>,
|
||||
pub struct AllocationProvenance<Prov> {
|
||||
dest_provenance: Vec<(Size, Prov)>,
|
||||
}
|
||||
|
||||
impl<Prov: Copy, Extra> Allocation<Prov, Extra> {
|
||||
pub fn prepare_relocation_copy(
|
||||
pub fn prepare_provenance_copy(
|
||||
&self,
|
||||
cx: &impl HasDataLayout,
|
||||
src: AllocRange,
|
||||
dest: Size,
|
||||
count: u64,
|
||||
) -> AllocationRelocations<Prov> {
|
||||
let relocations = self.get_relocations(cx, src);
|
||||
if relocations.is_empty() {
|
||||
return AllocationRelocations { dest_relocations: Vec::new() };
|
||||
) -> AllocationProvenance<Prov> {
|
||||
let provenance = self.range_get_provenance(cx, src);
|
||||
if provenance.is_empty() {
|
||||
return AllocationProvenance { dest_provenance: Vec::new() };
|
||||
}
|
||||
|
||||
let size = src.size;
|
||||
let mut new_relocations = Vec::with_capacity(relocations.len() * (count as usize));
|
||||
let mut new_provenance = Vec::with_capacity(provenance.len() * (count as usize));
|
||||
|
||||
// If `count` is large, this is rather wasteful -- we are allocating a big array here, which
|
||||
// is mostly filled with redundant information since it's just N copies of the same `Prov`s
|
||||
// at slightly adjusted offsets. The reason we do this is so that in `mark_relocation_range`
|
||||
// at slightly adjusted offsets. The reason we do this is so that in `mark_provenance_range`
|
||||
// we can use `insert_presorted`. That wouldn't work with an `Iterator` that just produces
|
||||
// the right sequence of relocations for all N copies.
|
||||
// the right sequence of provenance for all N copies.
|
||||
for i in 0..count {
|
||||
new_relocations.extend(relocations.iter().map(|&(offset, reloc)| {
|
||||
new_provenance.extend(provenance.iter().map(|&(offset, reloc)| {
|
||||
// compute offset for current repetition
|
||||
let dest_offset = dest + size * i; // `Size` operations
|
||||
(
|
||||
|
@ -681,17 +654,17 @@ impl<Prov: Copy, Extra> Allocation<Prov, Extra> {
|
|||
}));
|
||||
}
|
||||
|
||||
AllocationRelocations { dest_relocations: new_relocations }
|
||||
AllocationProvenance { dest_provenance: new_provenance }
|
||||
}
|
||||
|
||||
/// Applies a relocation copy.
|
||||
/// The affected range, as defined in the parameters to `prepare_relocation_copy` is expected
|
||||
/// to be clear of relocations.
|
||||
/// Applies a provenance copy.
|
||||
/// The affected range, as defined in the parameters to `prepare_provenance_copy` is expected
|
||||
/// to be clear of provenance.
|
||||
///
|
||||
/// This is dangerous to use as it can violate internal `Allocation` invariants!
|
||||
/// It only exists to support an efficient implementation of `mem_copy_repeatedly`.
|
||||
pub fn mark_relocation_range(&mut self, relocations: AllocationRelocations<Prov>) {
|
||||
self.relocations.0.insert_presorted(relocations.dest_relocations);
|
||||
pub fn mark_provenance_range(&mut self, provenance: AllocationProvenance<Prov>) {
|
||||
self.provenance.0.insert_presorted(provenance.dest_provenance);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -401,14 +401,18 @@ impl fmt::Display for UndefinedBehaviorInfo {
|
|||
pub enum UnsupportedOpInfo {
|
||||
/// Free-form case. Only for errors that are never caught!
|
||||
Unsupported(String),
|
||||
/// Encountered a pointer where we needed raw bytes.
|
||||
ReadPointerAsBytes,
|
||||
/// Overwriting parts of a pointer; the resulting state cannot be represented in our
|
||||
/// `Allocation` data structure. See <https://github.com/rust-lang/miri/issues/2181>.
|
||||
PartialPointerOverwrite(Pointer<AllocId>),
|
||||
/// Attempting to `copy` parts of a pointer to somewhere else; the resulting state cannot be
|
||||
/// represented in our `Allocation` data structure. See
|
||||
/// <https://github.com/rust-lang/miri/issues/2181>.
|
||||
PartialPointerCopy(Pointer<AllocId>),
|
||||
//
|
||||
// The variants below are only reachable from CTFE/const prop, miri will never emit them.
|
||||
//
|
||||
/// Encountered a pointer where we needed raw bytes.
|
||||
ReadPointerAsBytes,
|
||||
/// Accessing thread local statics
|
||||
ThreadLocalStatic(DefId),
|
||||
/// Accessing an unsupported extern static.
|
||||
|
@ -420,10 +424,13 @@ impl fmt::Display for UnsupportedOpInfo {
|
|||
use UnsupportedOpInfo::*;
|
||||
match self {
|
||||
Unsupported(ref msg) => write!(f, "{msg}"),
|
||||
ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes"),
|
||||
PartialPointerOverwrite(ptr) => {
|
||||
write!(f, "unable to overwrite parts of a pointer in memory at {ptr:?}")
|
||||
}
|
||||
PartialPointerCopy(ptr) => {
|
||||
write!(f, "unable to copy parts of a pointer from memory at {ptr:?}")
|
||||
}
|
||||
ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes"),
|
||||
ThreadLocalStatic(did) => write!(f, "cannot access thread local static ({did:?})"),
|
||||
ReadExternStatic(did) => write!(f, "cannot read from extern static ({did:?})"),
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar};
|
|||
|
||||
pub use self::allocation::{
|
||||
alloc_range, AllocRange, Allocation, ConstAllocation, InitChunk, InitChunkIter, InitMask,
|
||||
Relocations,
|
||||
ProvenanceMap,
|
||||
};
|
||||
|
||||
pub use self::pointer::{Pointer, PointerArithmetic, Provenance};
|
||||
|
|
|
@ -107,8 +107,12 @@ impl<T: HasDataLayout> PointerArithmetic for T {}
|
|||
/// pointer), but `derive` adds some unnecessary bounds.
|
||||
pub trait Provenance: Copy + fmt::Debug {
|
||||
/// Says whether the `offset` field of `Pointer`s with this provenance is the actual physical address.
|
||||
/// If `true, ptr-to-int casts work by simply discarding the provenance.
|
||||
/// If `false`, ptr-to-int casts are not supported. The offset *must* be relative in that case.
|
||||
/// - If `false`, the offset *must* be relative. This means the bytes representing a pointer are
|
||||
/// different from what the Abstract Machine prescribes, so the interpreter must prevent any
|
||||
/// operation that would inspect the underlying bytes of a pointer, such as ptr-to-int
|
||||
/// transmutation. A `ReadPointerAsBytes` error will be raised in such situations.
|
||||
/// - If `true`, the interpreter will permit operations to inspect the underlying bytes of a
|
||||
/// pointer, and implement ptr-to-int transmutation by stripping provenance.
|
||||
const OFFSET_IS_ADDR: bool;
|
||||
|
||||
/// We also use this trait to control whether to abort execution when a pointer is being partially overwritten
|
||||
|
@ -125,6 +129,9 @@ pub trait Provenance: Copy + fmt::Debug {
|
|||
/// Otherwise this function is best-effort (but must agree with `Machine::ptr_get_alloc`).
|
||||
/// (Identifying the offset in that allocation, however, is harder -- use `Memory::ptr_get_alloc` for that.)
|
||||
fn get_alloc_id(self) -> Option<AllocId>;
|
||||
|
||||
/// Defines the 'join' of provenance: what happens when doing a pointer load and different bytes have different provenance.
|
||||
fn join(left: Option<Self>, right: Option<Self>) -> Option<Self>;
|
||||
}
|
||||
|
||||
impl Provenance for AllocId {
|
||||
|
@ -152,6 +159,10 @@ impl Provenance for AllocId {
|
|||
fn get_alloc_id(self) -> Option<AllocId> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn join(_left: Option<Self>, _right: Option<Self>) -> Option<Self> {
|
||||
panic!("merging provenance is not supported when `OFFSET_IS_ADDR` is false")
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a pointer in the Miri engine.
|
||||
|
|
|
@ -130,9 +130,7 @@ pub enum Scalar<Prov = AllocId> {
|
|||
/// The raw bytes of a simple value.
|
||||
Int(ScalarInt),
|
||||
|
||||
/// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
|
||||
/// relocations, but a `Scalar` is only large enough to contain one, so we just represent the
|
||||
/// relocation and its associated offset together as a `Pointer` here.
|
||||
/// A pointer.
|
||||
///
|
||||
/// We also store the size of the pointer, such that a `Scalar` always knows how big it is.
|
||||
/// The size is always the pointer size of the current target, but this is not information
|
||||
|
@ -509,7 +507,7 @@ pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) ->
|
|||
if let ConstValue::Slice { data, start, end } = val {
|
||||
let len = end - start;
|
||||
data.inner()
|
||||
.get_bytes(
|
||||
.get_bytes_strip_provenance(
|
||||
cx,
|
||||
AllocRange { start: Size::from_bytes(start), size: Size::from_bytes(len) },
|
||||
)
|
||||
|
|
|
@ -2687,8 +2687,8 @@ fn pretty_print_const_value<'tcx>(
|
|||
match inner.kind() {
|
||||
ty::Slice(t) => {
|
||||
if *t == u8_type {
|
||||
// The `inspect` here is okay since we checked the bounds, and there are
|
||||
// no relocations (we have an active slice reference here). We don't use
|
||||
// The `inspect` here is okay since we checked the bounds, and `u8` carries
|
||||
// no provenance (we have an active slice reference here). We don't use
|
||||
// this result to affect interpreter execution.
|
||||
let byte_str = data
|
||||
.inner()
|
||||
|
@ -2698,8 +2698,8 @@ fn pretty_print_const_value<'tcx>(
|
|||
}
|
||||
}
|
||||
ty::Str => {
|
||||
// The `inspect` here is okay since we checked the bounds, and there are no
|
||||
// relocations (we have an active `str` reference here). We don't use this
|
||||
// The `inspect` here is okay since we checked the bounds, and `str` carries
|
||||
// no provenance (we have an active `str` reference here). We don't use this
|
||||
// result to affect interpreter execution.
|
||||
let slice = data
|
||||
.inner()
|
||||
|
@ -2714,7 +2714,7 @@ fn pretty_print_const_value<'tcx>(
|
|||
let n = n.kind().try_to_bits(tcx.data_layout.pointer_size).unwrap();
|
||||
// cast is ok because we already checked for pointer size (32 or 64 bit) above
|
||||
let range = AllocRange { start: offset, size: Size::from_bytes(n) };
|
||||
let byte_str = alloc.inner().get_bytes(&tcx, range).unwrap();
|
||||
let byte_str = alloc.inner().get_bytes_strip_provenance(&tcx, range).unwrap();
|
||||
fmt.write_str("*")?;
|
||||
pretty_print_byte_str(fmt, byte_str)?;
|
||||
return Ok(());
|
||||
|
|
|
@ -676,7 +676,7 @@ pub fn write_allocations<'tcx>(
|
|||
fn alloc_ids_from_alloc(
|
||||
alloc: ConstAllocation<'_>,
|
||||
) -> impl DoubleEndedIterator<Item = AllocId> + '_ {
|
||||
alloc.inner().relocations().values().map(|id| *id)
|
||||
alloc.inner().provenance().values().map(|id| *id)
|
||||
}
|
||||
|
||||
fn alloc_ids_from_const_val(val: ConstValue<'_>) -> impl Iterator<Item = AllocId> + '_ {
|
||||
|
@ -778,7 +778,7 @@ pub fn write_allocations<'tcx>(
|
|||
/// If the allocation is small enough to fit into a single line, no start address is given.
|
||||
/// After the hex dump, an ascii dump follows, replacing all unprintable characters (control
|
||||
/// characters or characters whose value is larger than 127) with a `.`
|
||||
/// This also prints relocations adequately.
|
||||
/// This also prints provenance adequately.
|
||||
pub fn display_allocation<'a, 'tcx, Prov, Extra>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
alloc: &'a Allocation<Prov, Extra>,
|
||||
|
@ -873,34 +873,34 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>(
|
|||
if i != line_start {
|
||||
write!(w, " ")?;
|
||||
}
|
||||
if let Some(&prov) = alloc.relocations().get(&i) {
|
||||
// Memory with a relocation must be defined
|
||||
if let Some(&prov) = alloc.provenance().get(&i) {
|
||||
// Memory with provenance must be defined
|
||||
assert!(alloc.init_mask().is_range_initialized(i, i + ptr_size).is_ok());
|
||||
let j = i.bytes_usize();
|
||||
let offset = alloc
|
||||
.inspect_with_uninit_and_ptr_outside_interpreter(j..j + ptr_size.bytes_usize());
|
||||
let offset = read_target_uint(tcx.data_layout.endian, offset).unwrap();
|
||||
let offset = Size::from_bytes(offset);
|
||||
let relocation_width = |bytes| bytes * 3;
|
||||
let provenance_width = |bytes| bytes * 3;
|
||||
let ptr = Pointer::new(prov, offset);
|
||||
let mut target = format!("{:?}", ptr);
|
||||
if target.len() > relocation_width(ptr_size.bytes_usize() - 1) {
|
||||
if target.len() > provenance_width(ptr_size.bytes_usize() - 1) {
|
||||
// This is too long, try to save some space.
|
||||
target = format!("{:#?}", ptr);
|
||||
}
|
||||
if ((i - line_start) + ptr_size).bytes_usize() > BYTES_PER_LINE {
|
||||
// This branch handles the situation where a relocation starts in the current line
|
||||
// This branch handles the situation where a provenance starts in the current line
|
||||
// but ends in the next one.
|
||||
let remainder = Size::from_bytes(BYTES_PER_LINE) - (i - line_start);
|
||||
let overflow = ptr_size - remainder;
|
||||
let remainder_width = relocation_width(remainder.bytes_usize()) - 2;
|
||||
let overflow_width = relocation_width(overflow.bytes_usize() - 1) + 1;
|
||||
let remainder_width = provenance_width(remainder.bytes_usize()) - 2;
|
||||
let overflow_width = provenance_width(overflow.bytes_usize() - 1) + 1;
|
||||
ascii.push('╾');
|
||||
for _ in 0..remainder.bytes() - 1 {
|
||||
ascii.push('─');
|
||||
}
|
||||
if overflow_width > remainder_width && overflow_width >= target.len() {
|
||||
// The case where the relocation fits into the part in the next line
|
||||
// The case where the provenance fits into the part in the next line
|
||||
write!(w, "╾{0:─^1$}", "", remainder_width)?;
|
||||
line_start =
|
||||
write_allocation_newline(w, line_start, &ascii, pos_width, prefix)?;
|
||||
|
@ -921,11 +921,11 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>(
|
|||
i += ptr_size;
|
||||
continue;
|
||||
} else {
|
||||
// This branch handles a relocation that starts and ends in the current line.
|
||||
let relocation_width = relocation_width(ptr_size.bytes_usize() - 1);
|
||||
oversized_ptr(&mut target, relocation_width);
|
||||
// This branch handles a provenance that starts and ends in the current line.
|
||||
let provenance_width = provenance_width(ptr_size.bytes_usize() - 1);
|
||||
oversized_ptr(&mut target, provenance_width);
|
||||
ascii.push('╾');
|
||||
write!(w, "╾{0:─^1$}╼", target, relocation_width)?;
|
||||
write!(w, "╾{0:─^1$}╼", target, provenance_width)?;
|
||||
for _ in 0..ptr_size.bytes() - 2 {
|
||||
ascii.push('─');
|
||||
}
|
||||
|
@ -935,7 +935,7 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>(
|
|||
} else if alloc.init_mask().is_range_initialized(i, i + Size::from_bytes(1)).is_ok() {
|
||||
let j = i.bytes_usize();
|
||||
|
||||
// Checked definedness (and thus range) and relocations. This access also doesn't
|
||||
// Checked definedness (and thus range) and provenance. This access also doesn't
|
||||
// influence interpreter execution but is only for debugging.
|
||||
let c = alloc.inspect_with_uninit_and_ptr_outside_interpreter(j..j + 1)[0];
|
||||
write!(w, "{:02x}", c)?;
|
||||
|
|
|
@ -113,7 +113,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
|
|||
}
|
||||
|
||||
// `Relocations` with default type parameters is a sorted map.
|
||||
impl<'a, Prov> HashStable<StableHashingContext<'a>> for mir::interpret::Relocations<Prov>
|
||||
impl<'a, Prov> HashStable<StableHashingContext<'a>> for mir::interpret::ProvenanceMap<Prov>
|
||||
where
|
||||
Prov: HashStable<StableHashingContext<'a>>,
|
||||
{
|
||||
|
|
|
@ -1275,7 +1275,7 @@ pub trait PrettyPrinter<'tcx>:
|
|||
let range =
|
||||
AllocRange { start: offset, size: Size::from_bytes(len) };
|
||||
if let Ok(byte_str) =
|
||||
alloc.inner().get_bytes(&self.tcx(), range)
|
||||
alloc.inner().get_bytes_strip_provenance(&self.tcx(), range)
|
||||
{
|
||||
p!(pretty_print_byte_str(byte_str))
|
||||
} else {
|
||||
|
@ -1536,6 +1536,34 @@ pub trait PrettyPrinter<'tcx>:
|
|||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn pretty_closure_as_impl(
|
||||
mut self,
|
||||
closure: ty::ClosureSubsts<'tcx>,
|
||||
) -> Result<Self::Const, Self::Error> {
|
||||
let sig = closure.sig();
|
||||
let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn);
|
||||
|
||||
write!(self, "impl ")?;
|
||||
self.wrap_binder(&sig, |sig, mut cx| {
|
||||
define_scoped_cx!(cx);
|
||||
|
||||
p!(print(kind), "(");
|
||||
for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() {
|
||||
if i > 0 {
|
||||
p!(", ");
|
||||
}
|
||||
p!(print(arg));
|
||||
}
|
||||
p!(")");
|
||||
|
||||
if !sig.output().is_unit() {
|
||||
p!(" -> ", print(sig.output()));
|
||||
}
|
||||
|
||||
Ok(cx)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// HACK(eddyb) boxed to avoid moving around a large struct by-value.
|
||||
|
@ -2450,6 +2478,11 @@ impl<'tcx> ty::PolyTraitPredicate<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub struct PrintClosureAsImpl<'tcx> {
|
||||
pub closure: ty::ClosureSubsts<'tcx>,
|
||||
}
|
||||
|
||||
forward_display_to_print! {
|
||||
ty::Region<'tcx>,
|
||||
Ty<'tcx>,
|
||||
|
@ -2542,6 +2575,10 @@ define_print_and_forward_display! {
|
|||
p!(print(self.0.trait_ref.print_only_trait_path()));
|
||||
}
|
||||
|
||||
PrintClosureAsImpl<'tcx> {
|
||||
p!(pretty_closure_as_impl(self.closure))
|
||||
}
|
||||
|
||||
ty::ParamTy {
|
||||
p!(write("{}", self.name))
|
||||
}
|
||||
|
|
|
@ -325,6 +325,10 @@ impl<'tcx> ClosureSubsts<'tcx> {
|
|||
_ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_as_impl_trait(self) -> ty::print::PrintClosureAsImpl<'tcx> {
|
||||
ty::print::PrintClosureAsImpl { closure: self }
|
||||
}
|
||||
}
|
||||
|
||||
/// Similar to `ClosureSubsts`; see the above documentation for more.
|
||||
|
|
|
@ -461,7 +461,7 @@ fn collect_items_rec<'tcx>(
|
|||
recursion_depth_reset = None;
|
||||
|
||||
if let Ok(alloc) = tcx.eval_static_initializer(def_id) {
|
||||
for &id in alloc.inner().relocations().values() {
|
||||
for &id in alloc.inner().provenance().values() {
|
||||
collect_miri(tcx, id, &mut neighbors);
|
||||
}
|
||||
}
|
||||
|
@ -1424,7 +1424,7 @@ fn collect_miri<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIte
|
|||
}
|
||||
GlobalAlloc::Memory(alloc) => {
|
||||
trace!("collecting {:?} with {:#?}", alloc_id, alloc);
|
||||
for &inner in alloc.inner().relocations().values() {
|
||||
for &inner in alloc.inner().provenance().values() {
|
||||
rustc_data_structures::stack::ensure_sufficient_stack(|| {
|
||||
collect_miri(tcx, inner, output);
|
||||
});
|
||||
|
@ -1463,7 +1463,7 @@ fn collect_const_value<'tcx>(
|
|||
match value {
|
||||
ConstValue::Scalar(Scalar::Ptr(ptr, _size)) => collect_miri(tcx, ptr.provenance, output),
|
||||
ConstValue::Slice { data: alloc, start: _, end: _ } | ConstValue::ByRef { alloc, .. } => {
|
||||
for &id in alloc.inner().relocations().values() {
|
||||
for &id in alloc.inner().provenance().values() {
|
||||
collect_miri(tcx, id, output);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1172,16 +1172,6 @@ impl<'a> Resolver<'a> {
|
|||
Scope::Module(module, _) => {
|
||||
this.add_module_candidates(module, &mut suggestions, filter_fn);
|
||||
}
|
||||
Scope::RegisteredAttrs => {
|
||||
let res = Res::NonMacroAttr(NonMacroAttrKind::Registered);
|
||||
if filter_fn(res) {
|
||||
suggestions.extend(
|
||||
this.registered_attrs
|
||||
.iter()
|
||||
.map(|ident| TypoSuggestion::typo_from_res(ident.name, res)),
|
||||
);
|
||||
}
|
||||
}
|
||||
Scope::MacroUsePrelude => {
|
||||
suggestions.extend(this.macro_use_prelude.iter().filter_map(
|
||||
|(name, binding)| {
|
||||
|
|
|
@ -127,7 +127,6 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
Scope::CrateRoot => true,
|
||||
Scope::Module(..) => true,
|
||||
Scope::RegisteredAttrs => use_prelude,
|
||||
Scope::MacroUsePrelude => use_prelude || rust_2015,
|
||||
Scope::BuiltinAttrs => true,
|
||||
Scope::ExternPrelude => use_prelude || is_absolute_path,
|
||||
|
@ -187,12 +186,11 @@ impl<'a> Resolver<'a> {
|
|||
match ns {
|
||||
TypeNS => Scope::ExternPrelude,
|
||||
ValueNS => Scope::StdLibPrelude,
|
||||
MacroNS => Scope::RegisteredAttrs,
|
||||
MacroNS => Scope::MacroUsePrelude,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Scope::RegisteredAttrs => Scope::MacroUsePrelude,
|
||||
Scope::MacroUsePrelude => Scope::StdLibPrelude,
|
||||
Scope::BuiltinAttrs => break, // nowhere else to search
|
||||
Scope::ExternPrelude if is_absolute_path => break,
|
||||
|
@ -556,14 +554,6 @@ impl<'a> Resolver<'a> {
|
|||
Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
|
||||
}
|
||||
}
|
||||
Scope::RegisteredAttrs => match this.registered_attrs.get(&ident).cloned() {
|
||||
Some(ident) => ok(
|
||||
Res::NonMacroAttr(NonMacroAttrKind::Registered),
|
||||
ident.span,
|
||||
this.arenas,
|
||||
),
|
||||
None => Err(Determinacy::Determined),
|
||||
},
|
||||
Scope::MacroUsePrelude => {
|
||||
match this.macro_use_prelude.get(&ident.name).cloned() {
|
||||
Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
|
||||
|
|
|
@ -108,7 +108,6 @@ enum Scope<'a> {
|
|||
// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
|
||||
// lint if it should be reported.
|
||||
Module(Module<'a>, Option<NodeId>),
|
||||
RegisteredAttrs,
|
||||
MacroUsePrelude,
|
||||
BuiltinAttrs,
|
||||
ExternPrelude,
|
||||
|
@ -976,7 +975,6 @@ pub struct Resolver<'a> {
|
|||
/// A small map keeping true kinds of built-in macros that appear to be fn-like on
|
||||
/// the surface (`macro` items in libcore), but are actually attributes or derives.
|
||||
builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>,
|
||||
registered_attrs: FxHashSet<Ident>,
|
||||
registered_tools: RegisteredTools,
|
||||
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
|
||||
macro_map: FxHashMap<DefId, MacroData>,
|
||||
|
@ -1253,8 +1251,7 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
let (registered_attrs, registered_tools) =
|
||||
macros::registered_attrs_and_tools(session, &krate.attrs);
|
||||
let registered_tools = macros::registered_tools(session, &krate.attrs);
|
||||
|
||||
let features = session.features_untracked();
|
||||
|
||||
|
@ -1319,7 +1316,6 @@ impl<'a> Resolver<'a> {
|
|||
macro_names: FxHashSet::default(),
|
||||
builtin_macros: Default::default(),
|
||||
builtin_macro_kinds: Default::default(),
|
||||
registered_attrs,
|
||||
registered_tools,
|
||||
macro_use_prelude: FxHashMap::default(),
|
||||
macro_map: FxHashMap::default(),
|
||||
|
|
|
@ -112,47 +112,32 @@ fn fast_print_path(path: &ast::Path) -> Symbol {
|
|||
}
|
||||
}
|
||||
|
||||
/// The code common between processing `#![register_tool]` and `#![register_attr]`.
|
||||
fn registered_idents(
|
||||
sess: &Session,
|
||||
attrs: &[ast::Attribute],
|
||||
attr_name: Symbol,
|
||||
descr: &str,
|
||||
) -> FxHashSet<Ident> {
|
||||
let mut registered = FxHashSet::default();
|
||||
for attr in sess.filter_by_name(attrs, attr_name) {
|
||||
pub(crate) fn registered_tools(sess: &Session, attrs: &[ast::Attribute]) -> FxHashSet<Ident> {
|
||||
let mut registered_tools = FxHashSet::default();
|
||||
for attr in sess.filter_by_name(attrs, sym::register_tool) {
|
||||
for nested_meta in attr.meta_item_list().unwrap_or_default() {
|
||||
match nested_meta.ident() {
|
||||
Some(ident) => {
|
||||
if let Some(old_ident) = registered.replace(ident) {
|
||||
let msg = format!("{} `{}` was already registered", descr, ident);
|
||||
if let Some(old_ident) = registered_tools.replace(ident) {
|
||||
let msg = format!("{} `{}` was already registered", "tool", ident);
|
||||
sess.struct_span_err(ident.span, &msg)
|
||||
.span_label(old_ident.span, "already registered here")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let msg = format!("`{}` only accepts identifiers", attr_name);
|
||||
let msg = format!("`{}` only accepts identifiers", sym::register_tool);
|
||||
let span = nested_meta.span();
|
||||
sess.struct_span_err(span, &msg).span_label(span, "not an identifier").emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
registered
|
||||
}
|
||||
|
||||
pub(crate) fn registered_attrs_and_tools(
|
||||
sess: &Session,
|
||||
attrs: &[ast::Attribute],
|
||||
) -> (FxHashSet<Ident>, FxHashSet<Ident>) {
|
||||
let registered_attrs = registered_idents(sess, attrs, sym::register_attr, "attribute");
|
||||
let mut registered_tools = registered_idents(sess, attrs, sym::register_tool, "tool");
|
||||
// We implicitly add `rustfmt` and `clippy` to known tools,
|
||||
// but it's not an error to register them explicitly.
|
||||
let predefined_tools = [sym::clippy, sym::rustfmt];
|
||||
registered_tools.extend(predefined_tools.iter().cloned().map(Ident::with_dummy_span));
|
||||
(registered_attrs, registered_tools)
|
||||
registered_tools
|
||||
}
|
||||
|
||||
// Some feature gates for inner attributes are reported as lints for backward compatibility.
|
||||
|
|
|
@ -690,13 +690,17 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
real_trait_pred = parent_trait_pred;
|
||||
}
|
||||
|
||||
// Skipping binder here, remapping below
|
||||
let real_ty = real_trait_pred.self_ty().skip_binder();
|
||||
if self.can_eq(obligation.param_env, real_ty, arg_ty).is_err() {
|
||||
let real_ty = real_trait_pred.self_ty();
|
||||
// We `erase_late_bound_regions` here because `make_subregion` does not handle
|
||||
// `ReLateBound`, and we don't particularly care about the regions.
|
||||
if self
|
||||
.can_eq(obligation.param_env, self.tcx.erase_late_bound_regions(real_ty), arg_ty)
|
||||
.is_err()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() {
|
||||
if let ty::Ref(region, base_ty, mutbl) = *real_ty.skip_binder().kind() {
|
||||
let mut autoderef = Autoderef::new(
|
||||
self,
|
||||
obligation.param_env,
|
||||
|
|
|
@ -506,30 +506,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
|
||||
// Only suggest changing the return type for methods that
|
||||
// haven't set a return type at all (and aren't `fn main()` or an impl).
|
||||
match (
|
||||
&fn_decl.output,
|
||||
found.is_suggestable(self.tcx, false),
|
||||
can_suggest,
|
||||
expected.is_unit(),
|
||||
) {
|
||||
(&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
|
||||
err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found });
|
||||
true
|
||||
}
|
||||
(&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
|
||||
// FIXME: if `found` could be `impl Iterator` or `impl Fn*`, we should suggest
|
||||
// that.
|
||||
err.subdiagnostic(AddReturnTypeSuggestion::MissingHere { span });
|
||||
true
|
||||
}
|
||||
(&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
|
||||
match &fn_decl.output {
|
||||
&hir::FnRetTy::DefaultReturn(span) if expected.is_unit() && !can_suggest => {
|
||||
// `fn main()` must return `()`, do not suggest changing return type
|
||||
err.subdiagnostic(ExpectedReturnTypeLabel::Unit { span });
|
||||
true
|
||||
return true;
|
||||
}
|
||||
// expectation was caused by something else, not the default return
|
||||
(&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
|
||||
(&hir::FnRetTy::Return(ref ty), _, _, _) => {
|
||||
&hir::FnRetTy::DefaultReturn(span) if expected.is_unit() => {
|
||||
if found.is_suggestable(self.tcx, false) {
|
||||
err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: found.to_string() });
|
||||
return true;
|
||||
} else if let ty::Closure(_, substs) = found.kind()
|
||||
// FIXME(compiler-errors): Get better at printing binders...
|
||||
&& let closure = substs.as_closure()
|
||||
&& closure.sig().is_suggestable(self.tcx, false)
|
||||
{
|
||||
err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: closure.print_as_impl_trait().to_string() });
|
||||
return true;
|
||||
} else {
|
||||
// FIXME: if `found` could be `impl Iterator` we should suggest that.
|
||||
err.subdiagnostic(AddReturnTypeSuggestion::MissingHere { span });
|
||||
return true
|
||||
}
|
||||
}
|
||||
&hir::FnRetTy::Return(ref ty) => {
|
||||
// Only point to return type if the expected type is the return type, as if they
|
||||
// are not, the expectation must have been caused by something else.
|
||||
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
|
||||
|
@ -546,9 +546,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.try_suggest_return_impl_trait(err, expected, ty, fn_id);
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// check whether the return type is a generic type with a trait bound
|
||||
|
|
|
@ -542,13 +542,13 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
|
|||
// For the wasm32 target statics with `#[link_section]` are placed into custom
|
||||
// sections of the final output file, but this isn't link custom sections of
|
||||
// other executable formats. Namely we can only embed a list of bytes,
|
||||
// nothing with pointers to anything else or relocations. If any relocation
|
||||
// show up, reject them here.
|
||||
// nothing with provenance (pointers to anything else). If any provenance
|
||||
// show up, reject it here.
|
||||
// `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
|
||||
// the consumer's responsibility to ensure all bytes that have been read
|
||||
// have defined values.
|
||||
if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id())
|
||||
&& alloc.inner().relocations().len() != 0
|
||||
&& alloc.inner().provenance().len() != 0
|
||||
{
|
||||
let msg = "statics with a custom `#[link_section]` must be a \
|
||||
simple list of bytes on the wasm target with no \
|
||||
|
|
|
@ -195,7 +195,7 @@ pub struct AddressOfTemporaryTaken {
|
|||
}
|
||||
|
||||
#[derive(SessionSubdiagnostic)]
|
||||
pub enum AddReturnTypeSuggestion<'tcx> {
|
||||
pub enum AddReturnTypeSuggestion {
|
||||
#[suggestion(
|
||||
typeck::add_return_type_add,
|
||||
code = "-> {found} ",
|
||||
|
@ -204,7 +204,7 @@ pub enum AddReturnTypeSuggestion<'tcx> {
|
|||
Add {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
found: Ty<'tcx>,
|
||||
found: String,
|
||||
},
|
||||
#[suggestion(
|
||||
typeck::add_return_type_missing_here,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::alloc::{Allocator, Global};
|
||||
use core::fmt;
|
||||
use core::iter::{FusedIterator, TrustedLen};
|
||||
use core::mem;
|
||||
use core::mem::{self, ManuallyDrop};
|
||||
use core::ptr::{self, NonNull};
|
||||
use core::slice::{self};
|
||||
|
||||
|
@ -65,6 +65,77 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> {
|
|||
pub fn allocator(&self) -> &A {
|
||||
unsafe { self.vec.as_ref().allocator() }
|
||||
}
|
||||
|
||||
/// Keep unyielded elements in the source `Vec`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(drain_keep_rest)]
|
||||
///
|
||||
/// let mut vec = vec!['a', 'b', 'c'];
|
||||
/// let mut drain = vec.drain(..);
|
||||
///
|
||||
/// assert_eq!(drain.next().unwrap(), 'a');
|
||||
///
|
||||
/// // This call keeps 'b' and 'c' in the vec.
|
||||
/// drain.keep_rest();
|
||||
///
|
||||
/// // If we wouldn't call `keep_rest()`,
|
||||
/// // `vec` would be empty.
|
||||
/// assert_eq!(vec, ['b', 'c']);
|
||||
/// ```
|
||||
#[unstable(feature = "drain_keep_rest", issue = "101122")]
|
||||
pub fn keep_rest(self) {
|
||||
// At this moment layout looks like this:
|
||||
//
|
||||
// [head] [yielded by next] [unyielded] [yielded by next_back] [tail]
|
||||
// ^-- start \_________/-- unyielded_len \____/-- self.tail_len
|
||||
// ^-- unyielded_ptr ^-- tail
|
||||
//
|
||||
// Normally `Drop` impl would drop [unyielded] and then move [tail] to the `start`.
|
||||
// Here we want to
|
||||
// 1. Move [unyielded] to `start`
|
||||
// 2. Move [tail] to a new start at `start + len(unyielded)`
|
||||
// 3. Update length of the original vec to `len(head) + len(unyielded) + len(tail)`
|
||||
// a. In case of ZST, this is the only thing we want to do
|
||||
// 4. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do
|
||||
let mut this = ManuallyDrop::new(self);
|
||||
|
||||
unsafe {
|
||||
let source_vec = this.vec.as_mut();
|
||||
|
||||
let start = source_vec.len();
|
||||
let tail = this.tail_start;
|
||||
|
||||
let unyielded_len = this.iter.len();
|
||||
let unyielded_ptr = this.iter.as_slice().as_ptr();
|
||||
|
||||
// ZSTs have no identity, so we don't need to move them around.
|
||||
let needs_move = mem::size_of::<T>() != 0;
|
||||
|
||||
if needs_move {
|
||||
let start_ptr = source_vec.as_mut_ptr().add(start);
|
||||
|
||||
// memmove back unyielded elements
|
||||
if unyielded_ptr != start_ptr {
|
||||
let src = unyielded_ptr;
|
||||
let dst = start_ptr;
|
||||
|
||||
ptr::copy(src, dst, unyielded_len);
|
||||
}
|
||||
|
||||
// memmove back untouched tail
|
||||
if tail != (start + unyielded_len) {
|
||||
let src = source_vec.as_ptr().add(tail);
|
||||
let dst = start_ptr.add(unyielded_len);
|
||||
ptr::copy(src, dst, this.tail_len);
|
||||
}
|
||||
}
|
||||
|
||||
source_vec.set_len(start + unyielded_len + this.tail_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::alloc::{Allocator, Global};
|
||||
use core::ptr::{self};
|
||||
use core::slice::{self};
|
||||
use core::mem::{self, ManuallyDrop};
|
||||
use core::ptr;
|
||||
use core::slice;
|
||||
|
||||
use super::Vec;
|
||||
|
||||
|
@ -54,6 +55,61 @@ where
|
|||
pub fn allocator(&self) -> &A {
|
||||
self.vec.allocator()
|
||||
}
|
||||
|
||||
/// Keep unyielded elements in the source `Vec`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(drain_filter)]
|
||||
/// #![feature(drain_keep_rest)]
|
||||
///
|
||||
/// let mut vec = vec!['a', 'b', 'c'];
|
||||
/// let mut drain = vec.drain_filter(|_| true);
|
||||
///
|
||||
/// assert_eq!(drain.next().unwrap(), 'a');
|
||||
///
|
||||
/// // This call keeps 'b' and 'c' in the vec.
|
||||
/// drain.keep_rest();
|
||||
///
|
||||
/// // If we wouldn't call `keep_rest()`,
|
||||
/// // `vec` would be empty.
|
||||
/// assert_eq!(vec, ['b', 'c']);
|
||||
/// ```
|
||||
#[unstable(feature = "drain_keep_rest", issue = "101122")]
|
||||
pub fn keep_rest(self) {
|
||||
// At this moment layout looks like this:
|
||||
//
|
||||
// _____________________/-- old_len
|
||||
// / \
|
||||
// [kept] [yielded] [tail]
|
||||
// \_______/ ^-- idx
|
||||
// \-- del
|
||||
//
|
||||
// Normally `Drop` impl would drop [tail] (via .for_each(drop), ie still calling `pred`)
|
||||
//
|
||||
// 1. Move [tail] after [kept]
|
||||
// 2. Update length of the original vec to `old_len - del`
|
||||
// a. In case of ZST, this is the only thing we want to do
|
||||
// 3. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do
|
||||
let mut this = ManuallyDrop::new(self);
|
||||
|
||||
unsafe {
|
||||
// ZSTs have no identity, so we don't need to move them around.
|
||||
let needs_move = mem::size_of::<T>() != 0;
|
||||
|
||||
if needs_move && this.idx < this.old_len && this.del > 0 {
|
||||
let ptr = this.vec.as_mut_ptr();
|
||||
let src = ptr.add(this.idx);
|
||||
let dst = src.sub(this.del);
|
||||
let tail_len = this.old_len - this.idx;
|
||||
src.copy_to(dst, tail_len);
|
||||
}
|
||||
|
||||
let new_len = this.old_len - this.del;
|
||||
this.vec.set_len(new_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#![feature(bench_black_box)]
|
||||
#![feature(strict_provenance)]
|
||||
#![feature(once_cell)]
|
||||
#![feature(drain_keep_rest)]
|
||||
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
|
|
@ -839,6 +839,36 @@ fn test_drain_leak() {
|
|||
assert_eq!(v, vec![D(0, false), D(1, false), D(6, false),]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drain_keep_rest() {
|
||||
let mut v = vec![0, 1, 2, 3, 4, 5, 6];
|
||||
let mut drain = v.drain(1..6);
|
||||
assert_eq!(drain.next(), Some(1));
|
||||
assert_eq!(drain.next_back(), Some(5));
|
||||
assert_eq!(drain.next(), Some(2));
|
||||
|
||||
drain.keep_rest();
|
||||
assert_eq!(v, &[0, 3, 4, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drain_keep_rest_all() {
|
||||
let mut v = vec![0, 1, 2, 3, 4, 5, 6];
|
||||
v.drain(1..6).keep_rest();
|
||||
assert_eq!(v, &[0, 1, 2, 3, 4, 5, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drain_keep_rest_none() {
|
||||
let mut v = vec![0, 1, 2, 3, 4, 5, 6];
|
||||
let mut drain = v.drain(1..6);
|
||||
|
||||
drain.by_ref().for_each(drop);
|
||||
|
||||
drain.keep_rest();
|
||||
assert_eq!(v, &[0, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_splice() {
|
||||
let mut v = vec![1, 2, 3, 4, 5];
|
||||
|
@ -1533,6 +1563,35 @@ fn drain_filter_unconsumed() {
|
|||
assert_eq!(vec, [2, 4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drain_filter_keep_rest() {
|
||||
let mut v = vec![0, 1, 2, 3, 4, 5, 6];
|
||||
let mut drain = v.drain_filter(|&mut x| x % 2 == 0);
|
||||
assert_eq!(drain.next(), Some(0));
|
||||
assert_eq!(drain.next(), Some(2));
|
||||
|
||||
drain.keep_rest();
|
||||
assert_eq!(v, &[1, 3, 4, 5, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drain_filter_keep_rest_all() {
|
||||
let mut v = vec![0, 1, 2, 3, 4, 5, 6];
|
||||
v.drain_filter(|_| true).keep_rest();
|
||||
assert_eq!(v, &[0, 1, 2, 3, 4, 5, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drain_filter_keep_rest_none() {
|
||||
let mut v = vec![0, 1, 2, 3, 4, 5, 6];
|
||||
let mut drain = v.drain_filter(|_| true);
|
||||
|
||||
drain.by_ref().for_each(drop);
|
||||
|
||||
drain.keep_rest();
|
||||
assert_eq!(v, &[]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reserve_exact() {
|
||||
// This is all the same as test_reserve
|
||||
|
|
|
@ -10,7 +10,7 @@ set -Eeuo pipefail
|
|||
# https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570
|
||||
unset GIT_DIR
|
||||
ROOT_DIR="$(git rev-parse --show-toplevel)"
|
||||
COMMAND="$ROOT_DIR/x.py test tidy --bless"
|
||||
COMMAND="$ROOT_DIR/x.py test tidy"
|
||||
|
||||
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
|
||||
COMMAND="python $COMMAND"
|
||||
|
|
|
@ -710,7 +710,7 @@ pre, .rustdoc.source .example-wrap {
|
|||
top: inherit;
|
||||
}
|
||||
|
||||
.content table:not(.table-display) {
|
||||
.content table {
|
||||
border-spacing: 0 5px;
|
||||
}
|
||||
.content td { vertical-align: top; }
|
||||
|
@ -763,15 +763,9 @@ pre, .rustdoc.source .example-wrap {
|
|||
margin-left: 20px;
|
||||
margin-top: -34px;
|
||||
}
|
||||
.content .docblock >.impl-items .table-display {
|
||||
margin: 0;
|
||||
}
|
||||
.content .docblock >.impl-items table td {
|
||||
padding: 0;
|
||||
}
|
||||
.content .docblock > .impl-items .table-display {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
display: block;
|
||||
|
@ -1563,33 +1557,6 @@ kbd {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.table-display {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.table-display tr td:first-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.table-display tr td:last-child {
|
||||
float: right;
|
||||
}
|
||||
.table-display .out-of-band {
|
||||
position: relative;
|
||||
font-size: 1.125rem;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.table-display td:hover .anchor {
|
||||
display: block;
|
||||
top: 2px;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
#main-content > ul {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
@ -2081,7 +2048,7 @@ in storage.js plus the media query with (min-width: 701px)
|
|||
height: 73px;
|
||||
}
|
||||
|
||||
#main-content > table:not(.table-display) td {
|
||||
#main-content > table td {
|
||||
word-break: break-word;
|
||||
width: 50%;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// compile-flags: -O
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(inline_const)]
|
||||
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
|
@ -9,3 +10,8 @@ pub fn maybe_uninit() -> [MaybeUninit<u8>; 3000] {
|
|||
// CHECK-NOT: memset
|
||||
[MaybeUninit::uninit(); 3000]
|
||||
}
|
||||
|
||||
pub fn maybe_uninit_const<T>() -> [MaybeUninit<T>; 8192] {
|
||||
// CHECK-NOT: memset
|
||||
[const { MaybeUninit::uninit() }; 8192]
|
||||
}
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
// check-pass
|
||||
// aux-build:lint-for-crate-rpass.rs
|
||||
// ignore-stage1
|
||||
// compile-flags: -D crate-not-okay
|
||||
|
||||
#![feature(plugin, register_attr, custom_inner_attributes)]
|
||||
|
||||
#![register_attr(
|
||||
crate_okay,
|
||||
crate_blue,
|
||||
crate_red,
|
||||
crate_grey,
|
||||
crate_green,
|
||||
)]
|
||||
|
||||
#![plugin(lint_for_crate_rpass)] //~ WARNING compiler plugins are deprecated
|
||||
#![crate_okay]
|
||||
#![crate_blue]
|
||||
#![crate_red]
|
||||
#![crate_grey]
|
||||
#![crate_green]
|
||||
|
||||
fn main() {}
|
|
@ -1,10 +0,0 @@
|
|||
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
|
||||
--> $DIR/issue-15778-pass.rs:16:1
|
||||
|
|
||||
LL | #![plugin(lint_for_crate_rpass)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
||||
|
|
||||
= note: `#[warn(deprecated)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#![feature(register_attr)]
|
||||
#![feature(register_tool)]
|
||||
|
||||
#![register_attr] //~ ERROR malformed `register_attr` attribute input
|
||||
#![register_tool] //~ ERROR malformed `register_tool` attribute input
|
||||
|
||||
#![register_attr(a::b)] //~ ERROR `register_attr` only accepts identifiers
|
||||
#![register_tool(a::b)] //~ ERROR `register_tool` only accepts identifiers
|
||||
|
||||
#![register_attr(attr, attr)] //~ ERROR attribute `attr` was already registered
|
||||
#![register_tool(tool, tool)] //~ ERROR tool `tool` was already registered
|
||||
|
||||
fn main() {}
|
|
@ -1,42 +0,0 @@
|
|||
error: `register_attr` only accepts identifiers
|
||||
--> $DIR/register-attr-tool-fail.rs:7:18
|
||||
|
|
||||
LL | #![register_attr(a::b)]
|
||||
| ^^^^ not an identifier
|
||||
|
||||
error: attribute `attr` was already registered
|
||||
--> $DIR/register-attr-tool-fail.rs:10:24
|
||||
|
|
||||
LL | #![register_attr(attr, attr)]
|
||||
| ---- ^^^^
|
||||
| |
|
||||
| already registered here
|
||||
|
||||
error: `register_tool` only accepts identifiers
|
||||
--> $DIR/register-attr-tool-fail.rs:8:18
|
||||
|
|
||||
LL | #![register_tool(a::b)]
|
||||
| ^^^^ not an identifier
|
||||
|
||||
error: tool `tool` was already registered
|
||||
--> $DIR/register-attr-tool-fail.rs:11:24
|
||||
|
|
||||
LL | #![register_tool(tool, tool)]
|
||||
| ---- ^^^^
|
||||
| |
|
||||
| already registered here
|
||||
|
||||
error: malformed `register_attr` attribute input
|
||||
--> $DIR/register-attr-tool-fail.rs:4:1
|
||||
|
|
||||
LL | #![register_attr]
|
||||
| ^^^^^^^^^^^^^^^^^ help: must be of the form: `#![register_attr(attr1, attr2, ...)]`
|
||||
|
||||
error: malformed `register_tool` attribute input
|
||||
--> $DIR/register-attr-tool-fail.rs:5:1
|
||||
|
|
||||
LL | #![register_tool]
|
||||
| ^^^^^^^^^^^^^^^^^ help: must be of the form: `#![register_tool(tool1, tool2, ...)]`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// edition:2018
|
||||
// compile-flags: -Zsave-analysis
|
||||
// ~^ Also regression test for #69588
|
||||
|
||||
#![feature(register_attr)]
|
||||
#![feature(register_tool)]
|
||||
|
||||
#![register_attr(attr)]
|
||||
#![register_tool(tool)]
|
||||
|
||||
use attr as renamed_attr; // OK
|
||||
use tool as renamed_tool; // OK
|
||||
|
||||
#[renamed_attr] //~ ERROR cannot use an explicitly registered attribute through an import
|
||||
#[renamed_tool::attr] //~ ERROR cannot use a tool module through an import
|
||||
//~| ERROR cannot use a tool module through an import
|
||||
fn main() {}
|
|
@ -1,38 +0,0 @@
|
|||
error: cannot use an explicitly registered attribute through an import
|
||||
--> $DIR/register-attr-tool-import.rs:14:3
|
||||
|
|
||||
LL | #[renamed_attr]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: the explicitly registered attribute imported here
|
||||
--> $DIR/register-attr-tool-import.rs:11:5
|
||||
|
|
||||
LL | use attr as renamed_attr; // OK
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: cannot use a tool module through an import
|
||||
--> $DIR/register-attr-tool-import.rs:15:3
|
||||
|
|
||||
LL | #[renamed_tool::attr]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: the tool module imported here
|
||||
--> $DIR/register-attr-tool-import.rs:12:5
|
||||
|
|
||||
LL | use tool as renamed_tool; // OK
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: cannot use a tool module through an import
|
||||
--> $DIR/register-attr-tool-import.rs:15:3
|
||||
|
|
||||
LL | #[renamed_tool::attr]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: the tool module imported here
|
||||
--> $DIR/register-attr-tool-import.rs:12:5
|
||||
|
|
||||
LL | use tool as renamed_tool; // OK
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
#![feature(register_attr)]
|
||||
#![feature(register_tool)]
|
||||
|
||||
#![register_attr(attr)]
|
||||
#![register_tool(tool)]
|
||||
|
||||
#[no_implicit_prelude]
|
||||
mod m {
|
||||
#[attr] //~ ERROR cannot find attribute `attr` in this scope
|
||||
#[tool::attr] //~ ERROR failed to resolve: use of undeclared crate or module `tool`
|
||||
fn check() {}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,15 +0,0 @@
|
|||
error[E0433]: failed to resolve: use of undeclared crate or module `tool`
|
||||
--> $DIR/register-attr-tool-prelude.rs:10:7
|
||||
|
|
||||
LL | #[tool::attr]
|
||||
| ^^^^ use of undeclared crate or module `tool`
|
||||
|
||||
error: cannot find attribute `attr` in this scope
|
||||
--> $DIR/register-attr-tool-prelude.rs:9:7
|
||||
|
|
||||
LL | #[attr]
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
|
@ -1,8 +0,0 @@
|
|||
#![deny(unused)]
|
||||
|
||||
#![feature(register_attr)]
|
||||
#![feature(register_tool)]
|
||||
|
||||
#[register_attr(attr)] //~ ERROR crate-level attribute should be an inner attribute
|
||||
#[register_tool(tool)] //~ ERROR crate-level attribute should be an inner attribute
|
||||
fn main() {}
|
|
@ -1,21 +0,0 @@
|
|||
error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
|
||||
--> $DIR/register-attr-tool-unused.rs:6:1
|
||||
|
|
||||
LL | #[register_attr(attr)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/register-attr-tool-unused.rs:1:9
|
||||
|
|
||||
LL | #![deny(unused)]
|
||||
| ^^^^^^
|
||||
= note: `#[deny(unused_attributes)]` implied by `#[deny(unused)]`
|
||||
|
||||
error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
|
||||
--> $DIR/register-attr-tool-unused.rs:7:1
|
||||
|
|
||||
LL | #[register_tool(tool)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// check-pass
|
||||
// compile-flags: --cfg foo
|
||||
|
||||
#![feature(register_attr)]
|
||||
#![feature(register_tool)]
|
||||
|
||||
#![register_attr(attr)]
|
||||
#![register_tool(tool)]
|
||||
#![register_tool(rustfmt, clippy)] // OK
|
||||
#![cfg_attr(foo, register_attr(conditional_attr))]
|
||||
#![cfg_attr(foo, register_tool(conditional_tool))]
|
||||
|
||||
#[attr]
|
||||
#[tool::attr]
|
||||
#[rustfmt::attr]
|
||||
#[clippy::attr]
|
||||
#[conditional_attr]
|
||||
#[conditional_tool::attr]
|
||||
fn main() {}
|
|
@ -55,9 +55,10 @@ error[E0080]: it is undefined behavior to use this value
|
|||
--> $DIR/forbidden_slices.rs:27:1
|
||||
|
|
||||
LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, size_of::<&u32>()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered a pointer, but expected plain (non-pointer) bytes
|
||||
| ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
= note: the raw bytes of the constant (size: 8, align: 4) {
|
||||
╾─ALLOC_ID─╼ 04 00 00 00 │ ╾──╼....
|
||||
}
|
||||
|
@ -170,9 +171,10 @@ error[E0080]: it is undefined behavior to use this value
|
|||
--> $DIR/forbidden_slices.rs:57:1
|
||||
|
|
||||
LL | pub static R5: &[u8] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered a pointer, but expected plain (non-pointer) bytes
|
||||
| ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
= note: the raw bytes of the constant (size: 8, align: 4) {
|
||||
╾ALLOC_ID─╼ 04 00 00 00 │ ╾──╼....
|
||||
}
|
||||
|
|
|
@ -55,9 +55,10 @@ error[E0080]: it is undefined behavior to use this value
|
|||
--> $DIR/forbidden_slices.rs:27:1
|
||||
|
|
||||
LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, size_of::<&u32>()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered a pointer, but expected plain (non-pointer) bytes
|
||||
| ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
= note: the raw bytes of the constant (size: 16, align: 8) {
|
||||
╾───────ALLOC_ID───────╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........
|
||||
}
|
||||
|
@ -170,9 +171,10 @@ error[E0080]: it is undefined behavior to use this value
|
|||
--> $DIR/forbidden_slices.rs:57:1
|
||||
|
|
||||
LL | pub static R5: &[u8] = unsafe {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered a pointer, but expected plain (non-pointer) bytes
|
||||
| ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
= note: the raw bytes of the constant (size: 16, align: 8) {
|
||||
╾──────ALLOC_ID───────╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:30:43
|
||||
|
@ -16,6 +18,8 @@ LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:34:45
|
||||
|
@ -25,6 +29,8 @@ LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uin
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:38:45
|
||||
|
@ -34,6 +40,8 @@ LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uin
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:42:45
|
||||
|
@ -43,6 +51,8 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:46:47
|
||||
|
@ -58,6 +68,8 @@ LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:54:45
|
||||
|
@ -67,6 +79,8 @@ LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:58:45
|
||||
|
@ -76,6 +90,8 @@ LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:62:45
|
||||
|
@ -85,6 +101,8 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:66:47
|
||||
|
@ -100,6 +118,8 @@ LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:74:45
|
||||
|
@ -109,6 +129,8 @@ LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:78:47
|
||||
|
@ -118,6 +140,8 @@ LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:82:47
|
||||
|
@ -127,6 +151,8 @@ LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:86:39
|
||||
|
@ -136,6 +162,8 @@ LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:90:41
|
||||
|
@ -145,6 +173,8 @@ LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:94:41
|
||||
|
@ -154,6 +184,8 @@ LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:98:41
|
||||
|
@ -163,6 +195,8 @@ LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:102:43
|
||||
|
@ -172,6 +206,8 @@ LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:106:39
|
||||
|
@ -181,6 +217,8 @@ LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:110:41
|
||||
|
@ -190,6 +228,8 @@ LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:114:41
|
||||
|
@ -199,6 +239,8 @@ LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:118:41
|
||||
|
@ -208,6 +250,8 @@ LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:122:43
|
||||
|
@ -217,6 +261,8 @@ LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:126:41
|
||||
|
@ -226,6 +272,8 @@ LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:130:41
|
||||
|
@ -235,6 +283,8 @@ LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:134:43
|
||||
|
@ -244,6 +294,8 @@ LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:138:43
|
||||
|
@ -253,6 +305,8 @@ LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.charact
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: aborting due to 29 previous errors
|
||||
|
||||
|
@ -267,6 +321,8 @@ LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -278,6 +334,8 @@ LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -289,6 +347,8 @@ LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uin
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -300,6 +360,8 @@ LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uin
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -311,6 +373,8 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -322,6 +386,8 @@ LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -333,6 +399,8 @@ LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -344,6 +412,8 @@ LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -355,6 +425,8 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -366,6 +438,8 @@ LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -377,6 +451,8 @@ LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -388,6 +464,8 @@ LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -399,6 +477,8 @@ LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -410,6 +490,8 @@ LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -421,6 +503,8 @@ LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -432,6 +516,8 @@ LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -443,6 +529,8 @@ LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -454,6 +542,8 @@ LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -465,6 +555,8 @@ LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -476,6 +568,8 @@ LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -487,6 +581,8 @@ LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -498,6 +594,8 @@ LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -509,6 +607,8 @@ LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -520,6 +620,8 @@ LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -531,6 +633,8 @@ LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -542,6 +646,8 @@ LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -553,4 +659,6 @@ LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.charact
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ LL | *(ptr as *mut u8) = 123;
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -26,4 +28,6 @@ LL | *(ptr as *mut u8) = 123;
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/ref_to_int_match.rs:7:14
|
||||
|
@ -32,4 +34,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/ref_to_int_match.rs:7:14
|
||||
|
@ -32,4 +34,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-enum.rs:30:1
|
||||
|
@ -27,6 +29,8 @@ LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= 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
|
||||
--> $DIR/ub-enum.rs:43:1
|
||||
|
@ -47,6 +51,8 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-enum.rs:49:1
|
||||
|
@ -56,6 +62,8 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-enum.rs:59:42
|
||||
|
@ -71,6 +79,8 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= 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
|
||||
--> $DIR/ub-enum.rs:82:1
|
||||
|
@ -130,6 +140,8 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -141,6 +153,8 @@ LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -152,6 +166,8 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -163,6 +179,8 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -174,4 +192,6 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-enum.rs:30:1
|
||||
|
@ -27,6 +29,8 @@ LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= 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
|
||||
--> $DIR/ub-enum.rs:43:1
|
||||
|
@ -47,6 +51,8 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-enum.rs:49:1
|
||||
|
@ -56,6 +62,8 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-enum.rs:59:42
|
||||
|
@ -71,6 +79,8 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= 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
|
||||
--> $DIR/ub-enum.rs:82:1
|
||||
|
@ -130,6 +140,8 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -141,6 +153,8 @@ LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -152,6 +166,8 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -163,6 +179,8 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -174,4 +192,6 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-ref-ptr.rs:35:39
|
||||
|
@ -60,6 +62,8 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-ref-ptr.rs:35:38
|
||||
|
@ -78,6 +82,8 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-ref-ptr.rs:41:85
|
||||
|
@ -168,6 +174,8 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -179,6 +187,8 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -201,6 +211,8 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
|
|
@ -51,6 +51,8 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-ref-ptr.rs:35:39
|
||||
|
@ -60,6 +62,8 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-ref-ptr.rs:35:38
|
||||
|
@ -78,6 +82,8 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-ref-ptr.rs:41:85
|
||||
|
@ -168,6 +174,8 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -179,6 +187,8 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -201,6 +211,8 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
|
|
@ -29,6 +29,8 @@ LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-wide-ptr.rs:46:1
|
||||
|
@ -38,6 +40,8 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= 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
|
||||
--> $DIR/ub-wide-ptr.rs:49:1
|
||||
|
@ -108,6 +112,8 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= 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
|
||||
--> $DIR/ub-wide-ptr.rs:80:1
|
||||
|
@ -128,6 +134,8 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= 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
|
||||
--> $DIR/ub-wide-ptr.rs:88:1
|
||||
|
@ -315,6 +323,8 @@ LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -326,6 +336,8 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -337,6 +349,8 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -348,6 +362,8 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
|
|
@ -29,6 +29,8 @@ LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ub-wide-ptr.rs:46:1
|
||||
|
@ -38,6 +40,8 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= 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
|
||||
--> $DIR/ub-wide-ptr.rs:49:1
|
||||
|
@ -108,6 +112,8 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= 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
|
||||
--> $DIR/ub-wide-ptr.rs:80:1
|
||||
|
@ -128,6 +134,8 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= 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
|
||||
--> $DIR/ub-wide-ptr.rs:88:1
|
||||
|
@ -315,6 +323,8 @@ LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -326,6 +336,8 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -337,6 +349,8 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -348,6 +362,8 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
|
|
@ -13,15 +13,15 @@ const INVALID_BOOL: () = unsafe {
|
|||
|
||||
const INVALID_PTR_IN_INT: () = unsafe {
|
||||
let _x: usize = transmute(&3u8);
|
||||
//[with_flag]~^ ERROR: evaluation of constant value failed
|
||||
//[with_flag]~| invalid value
|
||||
//[with_flag]~^ ERROR: any use of this value will cause an error
|
||||
//[with_flag]~| previously accepted
|
||||
};
|
||||
|
||||
const INVALID_SLICE_TO_USIZE_TRANSMUTE: () = unsafe {
|
||||
let x: &[u8] = &[0; 32];
|
||||
let _x: (usize, usize) = transmute(x);
|
||||
//[with_flag]~^ ERROR: evaluation of constant value failed
|
||||
//[with_flag]~| invalid value
|
||||
//[with_flag]~^ ERROR: any use of this value will cause an error
|
||||
//[with_flag]~| previously accepted
|
||||
};
|
||||
|
||||
const UNALIGNED_PTR: () = unsafe {
|
||||
|
|
|
@ -4,17 +4,33 @@ error[E0080]: evaluation of constant value failed
|
|||
LL | let _x: bool = transmute(3u8);
|
||||
| ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/detect-extra-ub.rs:15:21
|
||||
|
|
||||
LL | const INVALID_PTR_IN_INT: () = unsafe {
|
||||
| ----------------------------
|
||||
LL | let _x: usize = transmute(&3u8);
|
||||
| ^^^^^^^^^^^^^^^ constructing invalid value: encountered (potentially part of) a pointer, but expected an integer
|
||||
| ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/detect-extra-ub.rs:22:30
|
||||
|
|
||||
LL | const INVALID_SLICE_TO_USIZE_TRANSMUTE: () = unsafe {
|
||||
| ------------------------------------------
|
||||
LL | let x: &[u8] = &[0; 32];
|
||||
LL | let _x: (usize, usize) = transmute(x);
|
||||
| ^^^^^^^^^^^^ constructing invalid value at .0: encountered (potentially part of) a pointer, but expected an integer
|
||||
| ^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:28:20
|
||||
|
@ -49,7 +65,6 @@ LL | const UNALIGNED_READ: () = {
|
|||
LL | INNER;
|
||||
| ^^^^^ referenced constant has errors
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
|
||||
|
@ -57,6 +72,37 @@ error: aborting due to 6 previous errors
|
|||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/detect-extra-ub.rs:15:21
|
||||
|
|
||||
LL | const INVALID_PTR_IN_INT: () = unsafe {
|
||||
| ----------------------------
|
||||
LL | let _x: usize = transmute(&3u8);
|
||||
| ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/detect-extra-ub.rs:22:30
|
||||
|
|
||||
LL | const INVALID_SLICE_TO_USIZE_TRANSMUTE: () = unsafe {
|
||||
| ------------------------------------------
|
||||
LL | let x: &[u8] = &[0; 32];
|
||||
LL | let _x: (usize, usize) = transmute(x);
|
||||
| ^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/detect-extra-ub.rs:34:5
|
||||
|
|
||||
|
|
|
@ -2,9 +2,10 @@ error[E0080]: it is undefined behavior to use this value
|
|||
--> $DIR/issue-83182.rs:5:1
|
||||
|
|
||||
LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered a pointer in `str`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
= note: the raw bytes of the constant (size: 8, align: 4) {
|
||||
╾─alloc4──╼ 01 00 00 00 │ ╾──╼....
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@ error[E0080]: it is undefined behavior to use this value
|
|||
--> $DIR/issue-83182.rs:5:1
|
||||
|
|
||||
LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered a pointer in `str`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
= note: the raw bytes of the constant (size: 16, align: 8) {
|
||||
╾───────alloc4────────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
|
||||
}
|
||||
|
|
|
@ -4,5 +4,4 @@ use std::mem;
|
|||
struct MyStr(str);
|
||||
const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
|
||||
//~^ ERROR: it is undefined behavior to use this value
|
||||
//~| constructing invalid value at .<deref>.0: encountered a pointer in `str`
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// error-pattern unable to turn pointer into raw bytes
|
||||
// normalize-stderr-test: "alloc[0-9]+\+0x[a-z0-9]+" -> "ALLOC"
|
||||
#![feature(const_ptr_read)]
|
||||
|
||||
const C: () = unsafe {
|
||||
|
|
|
@ -4,12 +4,12 @@ error: any use of this value will cause an error
|
|||
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| unable to turn pointer into raw bytes
|
||||
| unable to copy parts of a pointer from memory at ALLOC
|
||||
| inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
||||
| inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
| inside `C` at $DIR/issue-miri-1910.rs:7:5
|
||||
| inside `C` at $DIR/issue-miri-1910.rs:8:5
|
||||
|
|
||||
::: $DIR/issue-miri-1910.rs:4:1
|
||||
::: $DIR/issue-miri-1910.rs:5:1
|
||||
|
|
||||
LL | const C: () = unsafe {
|
||||
| -----------
|
||||
|
@ -17,6 +17,8 @@ LL | const C: () = unsafe {
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -27,12 +29,12 @@ error: any use of this value will cause an error
|
|||
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| unable to turn pointer into raw bytes
|
||||
| unable to copy parts of a pointer from memory at ALLOC
|
||||
| inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
||||
| inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
| inside `C` at $DIR/issue-miri-1910.rs:7:5
|
||||
| inside `C` at $DIR/issue-miri-1910.rs:8:5
|
||||
|
|
||||
::: $DIR/issue-miri-1910.rs:4:1
|
||||
::: $DIR/issue-miri-1910.rs:5:1
|
||||
|
|
||||
LL | const C: () = unsafe {
|
||||
| -----------
|
||||
|
@ -40,4 +42,6 @@ LL | const C: () = unsafe {
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ error[E0080]: could not evaluate static initializer
|
|||
|
|
||||
LL | let _v = x + 0;
|
||||
| ^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
warning: skipping const checks
|
||||
|
|
||||
|
|
|
@ -27,6 +27,8 @@ LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) +
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ptr_comparisons.rs:70:27
|
||||
|
@ -36,6 +38,8 @@ LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -50,6 +54,8 @@ LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) +
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: any use of this value will cause an error
|
||||
|
@ -61,4 +67,6 @@ LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4
|
|||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
#![register_attr(attr)] //~ ERROR the `#[register_attr]` attribute is an experimental feature
|
||||
|
||||
fn main() {}
|
|
@ -1,12 +0,0 @@
|
|||
error[E0658]: the `#[register_attr]` attribute is an experimental feature
|
||||
--> $DIR/feature-gate-register_attr.rs:1:1
|
||||
|
|
||||
LL | #![register_attr(attr)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #66080 <https://github.com/rust-lang/rust/issues/66080> for more information
|
||||
= help: add `#![feature(register_attr)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
37
src/test/ui/generic-associated-types/issue-101020.rs
Normal file
37
src/test/ui/generic-associated-types/issue-101020.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
#![feature(generic_associated_types)]
|
||||
|
||||
pub trait LendingIterator {
|
||||
type Item<'a>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
fn consume<F>(self, _f: F)
|
||||
where
|
||||
Self: Sized,
|
||||
for<'a> Self::Item<'a>: FuncInput<'a, Self::Item<'a>>,
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: LendingIterator + ?Sized> LendingIterator for &mut I {
|
||||
type Item<'a> = I::Item<'a> where Self: 'a;
|
||||
}
|
||||
struct EmptyIter;
|
||||
impl LendingIterator for EmptyIter {
|
||||
type Item<'a> = &'a mut () where Self:'a;
|
||||
}
|
||||
pub trait FuncInput<'a, F>
|
||||
where
|
||||
F: Foo<Self>,
|
||||
Self: Sized,
|
||||
{
|
||||
}
|
||||
impl<'a, T, F: 'a> FuncInput<'a, F> for T where F: Foo<T> {}
|
||||
trait Foo<T> {}
|
||||
|
||||
fn map_test() {
|
||||
(&mut EmptyIter).consume(());
|
||||
//~^ ERROR the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satisfied
|
||||
}
|
||||
|
||||
fn main() {}
|
25
src/test/ui/generic-associated-types/issue-101020.stderr
Normal file
25
src/test/ui/generic-associated-types/issue-101020.stderr
Normal file
|
@ -0,0 +1,25 @@
|
|||
error[E0277]: the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satisfied
|
||||
--> $DIR/issue-101020.rs:33:5
|
||||
|
|
||||
LL | (&mut EmptyIter).consume(());
|
||||
| ^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `for<'a> Foo<&'a mut ()>` is not implemented for `&'a mut ()`
|
||||
|
|
||||
note: required for `&'a mut ()` to implement `for<'a> FuncInput<'a, &'a mut ()>`
|
||||
--> $DIR/issue-101020.rs:29:20
|
||||
|
|
||||
LL | impl<'a, T, F: 'a> FuncInput<'a, F> for T where F: Foo<T> {}
|
||||
| ^^^^^^^^^^^^^^^^ ^
|
||||
note: required by a bound in `LendingIterator::consume`
|
||||
--> $DIR/issue-101020.rs:11:33
|
||||
|
|
||||
LL | fn consume<F>(self, _f: F)
|
||||
| ------- required by a bound in this
|
||||
...
|
||||
LL | for<'a> Self::Item<'a>: FuncInput<'a, Self::Item<'a>>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `LendingIterator::consume`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
8
src/test/ui/impl-trait/issue-100075-2.rs
Normal file
8
src/test/ui/impl-trait/issue-100075-2.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
fn opaque<T>(t: T) -> impl Sized {
|
||||
//~^ ERROR cannot resolve opaque type
|
||||
//~| WARNING function cannot return without recursing
|
||||
opaque(Some(t))
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn main() {}
|
24
src/test/ui/impl-trait/issue-100075-2.stderr
Normal file
24
src/test/ui/impl-trait/issue-100075-2.stderr
Normal file
|
@ -0,0 +1,24 @@
|
|||
warning: function cannot return without recursing
|
||||
--> $DIR/issue-100075-2.rs:1:1
|
||||
|
|
||||
LL | fn opaque<T>(t: T) -> impl Sized {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
|
||||
...
|
||||
LL | opaque(Some(t))
|
||||
| --------------- recursive call site
|
||||
|
|
||||
= note: `#[warn(unconditional_recursion)]` on by default
|
||||
= help: a `loop` may express intention better if this is on purpose
|
||||
|
||||
error[E0720]: cannot resolve opaque type
|
||||
--> $DIR/issue-100075-2.rs:1:23
|
||||
|
|
||||
LL | fn opaque<T>(t: T) -> impl Sized {
|
||||
| ^^^^^^^^^^ recursive opaque type
|
||||
...
|
||||
LL | opaque(Some(t))
|
||||
| --------------- returning here with type `impl Sized`
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0720`.
|
21
src/test/ui/impl-trait/issue-100075.rs
Normal file
21
src/test/ui/impl-trait/issue-100075.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
trait Marker {}
|
||||
impl<T> Marker for T {}
|
||||
|
||||
fn maybe<T>(
|
||||
_t: T,
|
||||
) -> Option<
|
||||
//removing the line below makes it compile
|
||||
&'static T,
|
||||
> {
|
||||
None
|
||||
}
|
||||
|
||||
fn _g<T>(t: &'static T) -> &'static impl Marker {
|
||||
//~^ ERROR cannot resolve opaque type
|
||||
if let Some(t) = maybe(t) {
|
||||
return _g(t);
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() {}
|
12
src/test/ui/impl-trait/issue-100075.stderr
Normal file
12
src/test/ui/impl-trait/issue-100075.stderr
Normal file
|
@ -0,0 +1,12 @@
|
|||
error[E0720]: cannot resolve opaque type
|
||||
--> $DIR/issue-100075.rs:13:37
|
||||
|
|
||||
LL | fn _g<T>(t: &'static T) -> &'static impl Marker {
|
||||
| ^^^^^^^^^^^ recursive opaque type
|
||||
...
|
||||
LL | return _g(t);
|
||||
| ----- returning here with type `&impl Marker`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0720`.
|
|
@ -1,17 +0,0 @@
|
|||
// aux-build:derive-unstable-2.rs
|
||||
|
||||
#![feature(register_attr)]
|
||||
|
||||
#![register_attr(rustc_foo)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate derive_unstable_2;
|
||||
|
||||
#[derive(Unstable)]
|
||||
//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
|
||||
|
||||
struct A;
|
||||
|
||||
fn main() {
|
||||
foo();
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
error: attributes starting with `rustc` are reserved for use by the `rustc` compiler
|
||||
--> $DIR/expand-to-unstable-2.rs:10:10
|
||||
|
|
||||
LL | #[derive(Unstable)]
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the derive macro `Unstable` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
// gate-test-custom_inner_attributes
|
||||
// compile-flags: -Z span-debug --error-format human
|
||||
// aux-build:test-macros.rs
|
||||
// edition:2018
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
error: expected non-macro inner attribute, found attribute macro `print_attr`
|
||||
--> $DIR/inner-attrs.rs:63:12
|
||||
--> $DIR/inner-attrs.rs:64:12
|
||||
|
|
||||
LL | #![print_attr]
|
||||
| ^^^^^^^^^^ not a non-macro inner attribute
|
||||
|
||||
error: expected non-macro inner attribute, found attribute macro `print_attr`
|
||||
--> $DIR/inner-attrs.rs:67:12
|
||||
--> $DIR/inner-attrs.rs:68:12
|
||||
|
|
||||
LL | #![print_attr]
|
||||
| ^^^^^^^^^^ not a non-macro inner attribute
|
||||
|
||||
error: expected non-macro inner attribute, found attribute macro `print_attr`
|
||||
--> $DIR/inner-attrs.rs:71:12
|
||||
--> $DIR/inner-attrs.rs:72:12
|
||||
|
|
||||
LL | #![print_attr]
|
||||
| ^^^^^^^^^^ not a non-macro inner attribute
|
||||
|
||||
error: expected non-macro inner attribute, found attribute macro `print_attr`
|
||||
--> $DIR/inner-attrs.rs:75:12
|
||||
--> $DIR/inner-attrs.rs:76:12
|
||||
|
|
||||
LL | #![print_attr]
|
||||
| ^^^^^^^^^^ not a non-macro inner attribute
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,16 +0,0 @@
|
|||
// aux-build:test-macros.rs
|
||||
|
||||
// FIXME: https://github.com/rust-lang/rust/issues/41430
|
||||
// This is a temporary regression test for the ICE reported in #41211
|
||||
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![feature(register_attr)]
|
||||
|
||||
#![register_attr(identity_attr)]
|
||||
|
||||
#![identity_attr]
|
||||
//~^ ERROR `identity_attr` is ambiguous
|
||||
extern crate test_macros;
|
||||
use test_macros::identity_attr;
|
||||
|
||||
fn main() {}
|
|
@ -1,22 +0,0 @@
|
|||
error[E0659]: `identity_attr` is ambiguous
|
||||
--> $DIR/issue-41211.rs:11:4
|
||||
|
|
||||
LL | #![identity_attr]
|
||||
| ^^^^^^^^^^^^^ ambiguous name
|
||||
|
|
||||
= note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
|
||||
note: `identity_attr` could refer to the attribute macro imported here
|
||||
--> $DIR/issue-41211.rs:14:5
|
||||
|
|
||||
LL | use test_macros::identity_attr;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: use `crate::identity_attr` to refer to this attribute macro unambiguously
|
||||
note: `identity_attr` could also refer to the explicitly registered attribute defined here
|
||||
--> $DIR/issue-41211.rs:9:18
|
||||
|
|
||||
LL | #![register_attr(identity_attr)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0659`.
|
|
@ -1,12 +0,0 @@
|
|||
// gate-test-custom_inner_attributes
|
||||
|
||||
#![feature(register_attr)]
|
||||
|
||||
#![register_attr(foo)]
|
||||
|
||||
#[foo]
|
||||
mod foo {
|
||||
#![foo] //~ ERROR custom inner attributes are unstable
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,12 +0,0 @@
|
|||
error[E0658]: custom inner attributes are unstable
|
||||
--> $DIR/issue-36530.rs:9:8
|
||||
|
|
||||
LL | #![foo]
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
|
||||
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
13
src/test/ui/suggestions/return-closures.rs
Normal file
13
src/test/ui/suggestions/return-closures.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
fn foo() {
|
||||
//~^ HELP try adding a return type
|
||||
|x: &i32| 1i32
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn bar(i: impl Sized) {
|
||||
//~^ HELP a return type might be missing here
|
||||
|| i
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
27
src/test/ui/suggestions/return-closures.stderr
Normal file
27
src/test/ui/suggestions/return-closures.stderr
Normal file
|
@ -0,0 +1,27 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/return-closures.rs:3:5
|
||||
|
|
||||
LL | fn foo() {
|
||||
| - help: try adding a return type: `-> impl for<'r> Fn(&'r i32) -> i32`
|
||||
LL |
|
||||
LL | |x: &i32| 1i32
|
||||
| ^^^^^^^^^^^^^^ expected `()`, found closure
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found closure `[closure@$DIR/return-closures.rs:3:5: 3:14]`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-closures.rs:9:5
|
||||
|
|
||||
LL | fn bar(i: impl Sized) {
|
||||
| - help: a return type might be missing here: `-> _`
|
||||
LL |
|
||||
LL | || i
|
||||
| ^^^^ expected `()`, found closure
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found closure `[closure@$DIR/return-closures.rs:9:5: 9:7]`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Reference in a new issue