Skip to content

Commit 0631ea5

Browse files
committed
Auto merge of rust-lang#101183 - Dylan-DPC:rollup-6kewixv, r=Dylan-DPC
Rollup of 9 pull requests Successful merges: - rust-lang#95376 (Add `vec::Drain{,Filter}::keep_rest`) - rust-lang#100092 (Fall back when relating two opaques by substs in MIR typeck) - rust-lang#101019 (Suggest returning closure as `impl Fn`) - rust-lang#101022 (Erase late bound regions before comparing types in `suggest_dereferences`) - rust-lang#101101 (interpret: make read-pointer-as-bytes a CTFE-only error with extra information) - rust-lang#101123 (Remove `register_attr` feature) - rust-lang#101175 (Don't --bless in pre-push hook) - rust-lang#101176 (rustdoc: remove unused CSS selectors for `.table-display`) - rust-lang#101180 (Add another MaybeUninit array test with const) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents a0d0709 + ec95a92 commit 0631ea5

File tree

97 files changed

+1304
-994
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+1304
-994
lines changed

compiler/rustc_codegen_cranelift/src/constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
430430
let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec();
431431
data_ctx.define(bytes.into_boxed_slice());
432432

433-
for &(offset, alloc_id) in alloc.relocations().iter() {
433+
for &(offset, alloc_id) in alloc.provenance().iter() {
434434
let addend = {
435435
let endianness = tcx.data_layout.endian;
436436
let offset = offset.bytes() as usize;

compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
186186
let size = Size::from_bytes(
187187
4 * ret_lane_count, /* size_of([u32; ret_lane_count]) */
188188
);
189-
alloc.inner().get_bytes(fx, alloc_range(offset, size)).unwrap()
189+
alloc
190+
.inner()
191+
.get_bytes_strip_provenance(fx, alloc_range(offset, size))
192+
.unwrap()
190193
}
191194
_ => unreachable!("{:?}", idx_const),
192195
};

compiler/rustc_codegen_gcc/src/consts.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> {
127127
//
128128
// We could remove this hack whenever we decide to drop macOS 10.10 support.
129129
if self.tcx.sess.target.options.is_like_osx {
130-
// The `inspect` method is okay here because we checked relocations, and
130+
// The `inspect` method is okay here because we checked for provenance, and
131131
// because we are doing this access to inspect the final interpreter state
132132
// (not as part of the interpreter execution).
133133
//
@@ -296,17 +296,17 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
296296

297297
pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAllocation<'tcx>) -> RValue<'gcc> {
298298
let alloc = alloc.inner();
299-
let mut llvals = Vec::with_capacity(alloc.relocations().len() + 1);
299+
let mut llvals = Vec::with_capacity(alloc.provenance().len() + 1);
300300
let dl = cx.data_layout();
301301
let pointer_size = dl.pointer_size.bytes() as usize;
302302

303303
let mut next_offset = 0;
304-
for &(offset, alloc_id) in alloc.relocations().iter() {
304+
for &(offset, alloc_id) in alloc.provenance().iter() {
305305
let offset = offset.bytes();
306306
assert_eq!(offset as usize as u64, offset);
307307
let offset = offset as usize;
308308
if offset > next_offset {
309-
// This `inspect` is okay since we have checked that it is not within a relocation, it
309+
// This `inspect` is okay since we have checked that it is not within a pointer with provenance, it
310310
// is within the bounds of the allocation, and it doesn't affect interpreter execution
311311
// (we inspect the result after interpreter execution). Any undef byte is replaced with
312312
// some arbitrary byte value.
@@ -319,7 +319,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl
319319
read_target_uint( dl.endian,
320320
// This `inspect` is okay since it is within the bounds of the allocation, it doesn't
321321
// affect interpreter execution (we inspect the result after interpreter execution),
322-
// and we properly interpret the relocation as a relocation pointer offset.
322+
// and we properly interpret the provenance as a relocation pointer offset.
323323
alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
324324
)
325325
.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
336336
}
337337
if alloc.len() >= next_offset {
338338
let range = next_offset..alloc.len();
339-
// This `inspect` is okay since we have check that it is after all relocations, it is
339+
// This `inspect` is okay since we have check that it is after all provenance, it is
340340
// within the bounds of the allocation, and it doesn't affect interpreter execution (we
341341
// inspect the result after interpreter execution). Any undef byte is replaced with some
342342
// arbitrary byte value.

compiler/rustc_codegen_llvm/src/consts.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ use tracing::debug;
2727

2828
pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<'_>) -> &'ll Value {
2929
let alloc = alloc.inner();
30-
let mut llvals = Vec::with_capacity(alloc.relocations().len() + 1);
30+
let mut llvals = Vec::with_capacity(alloc.provenance().len() + 1);
3131
let dl = cx.data_layout();
3232
let pointer_size = dl.pointer_size.bytes() as usize;
3333

34-
// Note: this function may call `inspect_with_uninit_and_ptr_outside_interpreter`,
35-
// so `range` must be within the bounds of `alloc` and not contain or overlap a relocation.
34+
// Note: this function may call `inspect_with_uninit_and_ptr_outside_interpreter`, so `range`
35+
// must be within the bounds of `alloc` and not contain or overlap a pointer provenance.
3636
fn append_chunks_of_init_and_uninit_bytes<'ll, 'a, 'b>(
3737
llvals: &mut Vec<&'ll Value>,
3838
cx: &'a CodegenCx<'ll, 'b>,
@@ -79,12 +79,12 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
7979
}
8080

8181
let mut next_offset = 0;
82-
for &(offset, alloc_id) in alloc.relocations().iter() {
82+
for &(offset, alloc_id) in alloc.provenance().iter() {
8383
let offset = offset.bytes();
8484
assert_eq!(offset as usize as u64, offset);
8585
let offset = offset as usize;
8686
if offset > next_offset {
87-
// This `inspect` is okay since we have checked that it is not within a relocation, it
87+
// This `inspect` is okay since we have checked that there is no provenance, it
8888
// is within the bounds of the allocation, and it doesn't affect interpreter execution
8989
// (we inspect the result after interpreter execution).
9090
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<
9393
dl.endian,
9494
// This `inspect` is okay since it is within the bounds of the allocation, it doesn't
9595
// affect interpreter execution (we inspect the result after interpreter execution),
96-
// and we properly interpret the relocation as a relocation pointer offset.
96+
// and we properly interpret the provenance as a relocation pointer offset.
9797
alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
9898
)
9999
.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<
121121
}
122122
if alloc.len() >= next_offset {
123123
let range = next_offset..alloc.len();
124-
// This `inspect` is okay since we have check that it is after all relocations, it is
124+
// This `inspect` is okay since we have check that it is after all provenance, it is
125125
// within the bounds of the allocation, and it doesn't affect interpreter execution (we
126126
// inspect the result after interpreter execution).
127127
append_chunks_of_init_and_uninit_bytes(&mut llvals, cx, alloc, range);
@@ -479,15 +479,15 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
479479
//
480480
// We could remove this hack whenever we decide to drop macOS 10.10 support.
481481
if self.tcx.sess.target.is_like_osx {
482-
// The `inspect` method is okay here because we checked relocations, and
482+
// The `inspect` method is okay here because we checked for provenance, and
483483
// because we are doing this access to inspect the final interpreter state
484484
// (not as part of the interpreter execution).
485485
//
486486
// FIXME: This check requires that the (arbitrary) value of undefined bytes
487487
// happens to be zero. Instead, we should only check the value of defined bytes
488488
// and set all undefined bytes to zero if this allocation is headed for the
489489
// BSS.
490-
let all_bytes_are_zero = alloc.relocations().is_empty()
490+
let all_bytes_are_zero = alloc.provenance().is_empty()
491491
&& alloc
492492
.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len())
493493
.iter()
@@ -511,9 +511,9 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
511511
section.as_str().as_ptr().cast(),
512512
section.as_str().len() as c_uint,
513513
);
514-
assert!(alloc.relocations().is_empty());
514+
assert!(alloc.provenance().is_empty());
515515

516-
// The `inspect` method is okay here because we checked relocations, and
516+
// The `inspect` method is okay here because we checked for provenance, and
517517
// because we are doing this access to inspect the final interpreter state (not
518518
// as part of the interpreter execution).
519519
let bytes =

compiler/rustc_const_eval/src/const_eval/error.rs

+13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_span::{Span, Symbol};
1010
use super::InterpCx;
1111
use crate::interpret::{
1212
struct_error, ErrorHandled, FrameInfo, InterpError, InterpErrorInfo, Machine, MachineStopType,
13+
UnsupportedOpInfo,
1314
};
1415

1516
/// The CTFE machine has some custom error kinds.
@@ -149,6 +150,18 @@ impl<'tcx> ConstEvalErr<'tcx> {
149150
if let Some(span_msg) = span_msg {
150151
err.span_label(self.span, span_msg);
151152
}
153+
// Add some more context for select error types.
154+
match self.error {
155+
InterpError::Unsupported(
156+
UnsupportedOpInfo::ReadPointerAsBytes
157+
| UnsupportedOpInfo::PartialPointerOverwrite(_)
158+
| UnsupportedOpInfo::PartialPointerCopy(_),
159+
) => {
160+
err.help("this code performed an operation that depends on the underlying bytes representing a pointer");
161+
err.help("the absolute address of a pointer is not known at compile-time, so such operations are not supported");
162+
}
163+
_ => {}
164+
}
152165
// Add spans for the stacktrace. Don't print a single-line backtrace though.
153166
if self.stacktrace.len() > 1 {
154167
// Helper closure to print duplicated lines.

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr};
22
use crate::interpret::eval_nullary_intrinsic;
33
use crate::interpret::{
44
intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId,
5-
Immediate, InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking,
6-
StackPopCleanup,
5+
Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy,
6+
RefTracking, StackPopCleanup,
77
};
88

99
use rustc_hir::def::DefKind;
@@ -387,7 +387,9 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
387387
ecx.tcx,
388388
"it is undefined behavior to use this value",
389389
|diag| {
390-
diag.note(NOTE_ON_UNDEFINED_BEHAVIOR_ERROR);
390+
if matches!(err.error, InterpError::UndefinedBehavior(_)) {
391+
diag.note(NOTE_ON_UNDEFINED_BEHAVIOR_ERROR);
392+
}
391393
diag.note(&format!(
392394
"the raw bytes of the constant ({}",
393395
display_allocation(

compiler/rustc_const_eval/src/interpret/intern.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval:
134134
alloc.mutability = Mutability::Not;
135135
};
136136
// link the alloc id to the actual allocation
137-
leftover_allocations.extend(alloc.relocations().iter().map(|&(_, alloc_id)| alloc_id));
137+
leftover_allocations.extend(alloc.provenance().iter().map(|&(_, alloc_id)| alloc_id));
138138
let alloc = tcx.intern_const_alloc(alloc);
139139
tcx.set_alloc_id_memory(alloc_id, alloc);
140140
None
@@ -191,10 +191,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
191191
return Ok(true);
192192
};
193193

194-
// If there are no relocations in this allocation, it does not contain references
194+
// If there is no provenance in this allocation, it does not contain references
195195
// that point to another allocation, and we can avoid the interning walk.
196196
if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr, size, align)? {
197-
if !alloc.has_relocations() {
197+
if !alloc.has_provenance() {
198198
return Ok(false);
199199
}
200200
} else {
@@ -233,8 +233,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
233233
}
234234

235235
fn visit_value(&mut self, mplace: &MPlaceTy<'tcx>) -> InterpResult<'tcx> {
236-
// Handle Reference types, as these are the only relocations supported by const eval.
237-
// Raw pointers (and boxes) are handled by the `leftover_relocations` logic.
236+
// Handle Reference types, as these are the only types with provenance supported by const eval.
237+
// Raw pointers (and boxes) are handled by the `leftover_allocations` logic.
238238
let tcx = self.ecx.tcx;
239239
let ty = mplace.layout.ty;
240240
if let ty::Ref(_, referenced_ty, ref_mutability) = *ty.kind() {
@@ -410,7 +410,7 @@ pub fn intern_const_alloc_recursive<
410410
// references and a `leftover_allocations` set (where we only have a todo-list here).
411411
// So we hand-roll the interning logic here again.
412412
match intern_kind {
413-
// Statics may contain mutable allocations even behind relocations.
413+
// Statics may point to mutable allocations.
414414
// Even for immutable statics it would be ok to have mutable allocations behind
415415
// raw pointers, e.g. for `static FOO: *const AtomicUsize = &AtomicUsize::new(42)`.
416416
InternKind::Static(_) => {}
@@ -441,7 +441,7 @@ pub fn intern_const_alloc_recursive<
441441
}
442442
let alloc = tcx.intern_const_alloc(alloc);
443443
tcx.set_alloc_id_memory(alloc_id, alloc);
444-
for &(_, alloc_id) in alloc.inner().relocations().iter() {
444+
for &(_, alloc_id) in alloc.inner().provenance().iter() {
445445
if leftover_allocations.insert(alloc_id) {
446446
todo.push(alloc_id);
447447
}

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -687,10 +687,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
687687
let layout = self.layout_of(lhs.layout.ty.builtin_deref(true).unwrap().ty)?;
688688
assert!(!layout.is_unsized());
689689

690-
let lhs = self.read_pointer(lhs)?;
691-
let rhs = self.read_pointer(rhs)?;
692-
let lhs_bytes = self.read_bytes_ptr(lhs, layout.size)?;
693-
let rhs_bytes = self.read_bytes_ptr(rhs, layout.size)?;
690+
let get_bytes = |this: &InterpCx<'mir, 'tcx, M>,
691+
op: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>,
692+
size|
693+
-> InterpResult<'tcx, &[u8]> {
694+
let ptr = this.read_pointer(op)?;
695+
let Some(alloc_ref) = self.get_ptr_alloc(ptr, size, Align::ONE)? else {
696+
// zero-sized access
697+
return Ok(&[]);
698+
};
699+
if alloc_ref.has_provenance() {
700+
throw_ub_format!("`raw_eq` on bytes with provenance");
701+
}
702+
alloc_ref.get_bytes_strip_provenance()
703+
};
704+
705+
let lhs_bytes = get_bytes(self, lhs, layout.size)?;
706+
let rhs_bytes = get_bytes(self, rhs, layout.size)?;
694707
Ok(Scalar::from_bool(lhs_bytes == rhs_bytes))
695708
}
696709
}

compiler/rustc_const_eval/src/interpret/machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
315315
/// cache the result. (This relies on `AllocMap::get_or` being able to add the
316316
/// owned allocation to the map even when the map is shared.)
317317
///
318-
/// This must only fail if `alloc` contains relocations.
318+
/// This must only fail if `alloc` contains provenance.
319319
fn adjust_allocation<'b>(
320320
ecx: &InterpCx<'mir, 'tcx, Self>,
321321
id: AllocId,

0 commit comments

Comments
 (0)