Skip to content

Commit 04bf9f0

Browse files
committed
Auto merge of rust-lang#125689 - jieyouxu:rollup-e2waal9, r=jieyouxu
Rollup of 8 pull requests Successful merges: - rust-lang#124251 (Add an intrinsic for `ptr::metadata`) - rust-lang#124320 (Add `--print=check-cfg` to get the expected configs) - rust-lang#125226 (Make more of the test suite run on Mac Catalyst) - rust-lang#125381 (Silence some resolve errors when there have been glob import errors) - rust-lang#125633 (miri: avoid making a full copy of all new allocations) - rust-lang#125638 (Rewrite `lto-smoke`, `simple-rlib` and `mixing-deps` `run-make` tests in `rmake.rs` format) - rust-lang#125639 (Support `./x doc run-make-support --open`) - rust-lang#125664 (Tweak relations to no longer rely on `TypeTrace`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents da159eb + 093791c commit 04bf9f0

File tree

140 files changed

+1278
-465
lines changed

Some content is hidden

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

140 files changed

+1278
-465
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

+25-13
Original file line numberDiff line numberDiff line change
@@ -616,22 +616,34 @@ fn codegen_stmt<'tcx>(
616616
Rvalue::UnaryOp(un_op, ref operand) => {
617617
let operand = codegen_operand(fx, operand);
618618
let layout = operand.layout();
619-
let val = operand.load_scalar(fx);
620619
let res = match un_op {
621-
UnOp::Not => match layout.ty.kind() {
622-
ty::Bool => {
623-
let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
624-
CValue::by_val(res, layout)
620+
UnOp::Not => {
621+
let val = operand.load_scalar(fx);
622+
match layout.ty.kind() {
623+
ty::Bool => {
624+
let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
625+
CValue::by_val(res, layout)
626+
}
627+
ty::Uint(_) | ty::Int(_) => {
628+
CValue::by_val(fx.bcx.ins().bnot(val), layout)
629+
}
630+
_ => unreachable!("un op Not for {:?}", layout.ty),
625631
}
626-
ty::Uint(_) | ty::Int(_) => {
627-
CValue::by_val(fx.bcx.ins().bnot(val), layout)
632+
}
633+
UnOp::Neg => {
634+
let val = operand.load_scalar(fx);
635+
match layout.ty.kind() {
636+
ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout),
637+
ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout),
638+
_ => unreachable!("un op Neg for {:?}", layout.ty),
628639
}
629-
_ => unreachable!("un op Not for {:?}", layout.ty),
630-
},
631-
UnOp::Neg => match layout.ty.kind() {
632-
ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout),
633-
ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout),
634-
_ => unreachable!("un op Neg for {:?}", layout.ty),
640+
}
641+
UnOp::PtrMetadata => match layout.abi {
642+
Abi::Scalar(_) => CValue::zst(dest_layout),
643+
Abi::ScalarPair(_, _) => {
644+
CValue::by_val(operand.load_scalar_pair(fx).1, dest_layout)
645+
}
646+
_ => bug!("Unexpected `PtrToMetadata` operand: {operand:?}"),
635647
},
636648
};
637649
lval.write_cvalue(fx, res);

compiler/rustc_codegen_cranelift/src/constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ pub(crate) fn codegen_const_value<'tcx>(
100100
assert!(layout.is_sized(), "unsized const value");
101101

102102
if layout.is_zst() {
103-
return CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout);
103+
return CValue::zst(layout);
104104
}
105105

106106
match const_val {

compiler/rustc_codegen_cranelift/src/value_and_place.rs

+8
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ impl<'tcx> CValue<'tcx> {
9595
CValue(CValueInner::ByValPair(value, extra), layout)
9696
}
9797

98+
/// Create an instance of a ZST
99+
///
100+
/// The is represented by a dangling pointer of suitable alignment.
101+
pub(crate) fn zst(layout: TyAndLayout<'tcx>) -> CValue<'tcx> {
102+
assert!(layout.is_zst());
103+
CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout)
104+
}
105+
98106
pub(crate) fn layout(&self) -> TyAndLayout<'tcx> {
99107
self.1
100108
}

compiler/rustc_codegen_ssa/src/mir/operand.rs

+5
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
565565
for elem in place_ref.projection.iter() {
566566
match elem {
567567
mir::ProjectionElem::Field(ref f, _) => {
568+
debug_assert!(
569+
!o.layout.ty.is_any_ptr(),
570+
"Bad PlaceRef: destructing pointers should use cast/PtrMetadata, \
571+
but tried to access field {f:?} of pointer {o:?}",
572+
);
568573
o = o.extract_field(bx, f.index());
569574
}
570575
mir::ProjectionElem::Index(_)

compiler/rustc_codegen_ssa/src/mir/place.rs

+5
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
480480
cg_base = match *elem {
481481
mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
482482
mir::ProjectionElem::Field(ref field, _) => {
483+
debug_assert!(
484+
!cg_base.layout.ty.is_any_ptr(),
485+
"Bad PlaceRef: destructing pointers should use cast/PtrMetadata, \
486+
but tried to access field {field:?} of pointer {cg_base:?}",
487+
);
483488
cg_base.project_field(bx, field.index())
484489
}
485490
mir::ProjectionElem::OpaqueCast(ty) => {

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+26-8
Original file line numberDiff line numberDiff line change
@@ -623,19 +623,36 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
623623

624624
mir::Rvalue::UnaryOp(op, ref operand) => {
625625
let operand = self.codegen_operand(bx, operand);
626-
let lloperand = operand.immediate();
627626
let is_float = operand.layout.ty.is_floating_point();
628-
let llval = match op {
629-
mir::UnOp::Not => bx.not(lloperand),
627+
let (val, layout) = match op {
628+
mir::UnOp::Not => {
629+
let llval = bx.not(operand.immediate());
630+
(OperandValue::Immediate(llval), operand.layout)
631+
}
630632
mir::UnOp::Neg => {
631-
if is_float {
632-
bx.fneg(lloperand)
633+
let llval = if is_float {
634+
bx.fneg(operand.immediate())
635+
} else {
636+
bx.neg(operand.immediate())
637+
};
638+
(OperandValue::Immediate(llval), operand.layout)
639+
}
640+
mir::UnOp::PtrMetadata => {
641+
debug_assert!(operand.layout.ty.is_unsafe_ptr());
642+
let (_, meta) = operand.val.pointer_parts();
643+
assert_eq!(operand.layout.fields.count() > 1, meta.is_some());
644+
if let Some(meta) = meta {
645+
(OperandValue::Immediate(meta), operand.layout.field(self.cx, 1))
633646
} else {
634-
bx.neg(lloperand)
647+
(OperandValue::ZeroSized, bx.cx().layout_of(bx.tcx().types.unit))
635648
}
636649
}
637650
};
638-
OperandRef { val: OperandValue::Immediate(llval), layout: operand.layout }
651+
debug_assert!(
652+
val.is_expected_variant_for_type(self.cx, layout),
653+
"Made wrong variant {val:?} for type {layout:?}",
654+
);
655+
OperandRef { val, layout }
639656
}
640657

641658
mir::Rvalue::Discriminant(ref place) => {
@@ -718,8 +735,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
718735
let values = op.val.immediates_or_place().left_or_else(|p| {
719736
bug!("Field {field_idx:?} is {p:?} making {layout:?}");
720737
});
721-
inputs.extend(values);
722738
let scalars = self.value_kind(op.layout).scalars().unwrap();
739+
debug_assert_eq!(values.len(), scalars.len());
740+
inputs.extend(values);
723741
input_scalars.extend(scalars);
724742
}
725743

compiler/rustc_const_eval/src/const_eval/dummy_machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
174174
unimplemented!()
175175
}
176176

177-
fn init_frame_extra(
177+
fn init_frame(
178178
_ecx: &mut InterpCx<'tcx, Self>,
179179
_frame: interpret::Frame<'tcx, Self::Provenance>,
180180
) -> interpret::InterpResult<'tcx, interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>>

compiler/rustc_const_eval/src/const_eval/machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeInterpreter<'tcx> {
643643
}
644644

645645
#[inline(always)]
646-
fn init_frame_extra(
646+
fn init_frame(
647647
ecx: &mut InterpCx<'tcx, Self>,
648648
frame: Frame<'tcx>,
649649
) -> InterpResult<'tcx, Frame<'tcx>> {

compiler/rustc_const_eval/src/interpret/cast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
207207
assert!(cast_to.ty.is_unsafe_ptr());
208208
// Handle casting any ptr to raw ptr (might be a fat ptr).
209209
if cast_to.size == src.layout.size {
210-
// Thin or fat pointer that just hast the ptr kind of target type changed.
210+
// Thin or fat pointer that just has the ptr kind of target type changed.
211211
return Ok(ImmTy::from_immediate(**src, cast_to));
212212
} else {
213213
// Casting the metadata away from a fat ptr.

compiler/rustc_const_eval/src/interpret/eval_context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
819819
tracing_span: SpanGuard::new(),
820820
extra: (),
821821
};
822-
let frame = M::init_frame_extra(self, pre_frame)?;
822+
let frame = M::init_frame(self, pre_frame)?;
823823
self.stack_mut().push(frame);
824824

825825
// Make sure all the constants required by this frame evaluate successfully (post-monomorphization check).

compiler/rustc_const_eval/src/interpret/machine.rs

+41-17
Original file line numberDiff line numberDiff line change
@@ -329,27 +329,41 @@ pub trait Machine<'tcx>: Sized {
329329
ptr: Pointer<Self::Provenance>,
330330
) -> Option<(AllocId, Size, Self::ProvenanceExtra)>;
331331

332-
/// Called to adjust allocations to the Provenance and AllocExtra of this machine.
332+
/// Called to adjust global allocations to the Provenance and AllocExtra of this machine.
333333
///
334334
/// If `alloc` contains pointers, then they are all pointing to globals.
335335
///
336-
/// The way we construct allocations is to always first construct it without extra and then add
337-
/// the extra. This keeps uniform code paths for handling both allocations created by CTFE for
338-
/// globals, and allocations created by Miri during evaluation.
339-
///
340-
/// `kind` is the kind of the allocation being adjusted; it can be `None` when
341-
/// it's a global and `GLOBAL_KIND` is `None`.
342-
///
343336
/// This should avoid copying if no work has to be done! If this returns an owned
344337
/// allocation (because a copy had to be done to adjust things), machine memory will
345338
/// cache the result. (This relies on `AllocMap::get_or` being able to add the
346339
/// owned allocation to the map even when the map is shared.)
347-
fn adjust_allocation<'b>(
340+
fn adjust_global_allocation<'b>(
348341
ecx: &InterpCx<'tcx, Self>,
349342
id: AllocId,
350-
alloc: Cow<'b, Allocation>,
351-
kind: Option<MemoryKind<Self::MemoryKind>>,
352-
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
343+
alloc: &'b Allocation,
344+
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>
345+
{
346+
// The default implementation does a copy; CTFE machines have a more efficient implementation
347+
// based on their particular choice for `Provenance`, `AllocExtra`, and `Bytes`.
348+
let kind = Self::GLOBAL_KIND
349+
.expect("if GLOBAL_KIND is None, adjust_global_allocation must be overwritten");
350+
let alloc = alloc.adjust_from_tcx(&ecx.tcx, |ptr| ecx.global_root_pointer(ptr))?;
351+
let extra =
352+
Self::init_alloc_extra(ecx, id, MemoryKind::Machine(kind), alloc.size(), alloc.align)?;
353+
Ok(Cow::Owned(alloc.with_extra(extra)))
354+
}
355+
356+
/// Initialize the extra state of an allocation.
357+
///
358+
/// This is guaranteed to be called exactly once on all allocations that are accessed by the
359+
/// program.
360+
fn init_alloc_extra(
361+
ecx: &InterpCx<'tcx, Self>,
362+
id: AllocId,
363+
kind: MemoryKind<Self::MemoryKind>,
364+
size: Size,
365+
align: Align,
366+
) -> InterpResult<'tcx, Self::AllocExtra>;
353367

354368
/// Return a "root" pointer for the given allocation: the one that is used for direct
355369
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
@@ -473,7 +487,7 @@ pub trait Machine<'tcx>: Sized {
473487
}
474488

475489
/// Called immediately before a new stack frame gets pushed.
476-
fn init_frame_extra(
490+
fn init_frame(
477491
ecx: &mut InterpCx<'tcx, Self>,
478492
frame: Frame<'tcx, Self::Provenance>,
479493
) -> InterpResult<'tcx, Frame<'tcx, Self::Provenance, Self::FrameExtra>>;
@@ -590,13 +604,23 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
590604
}
591605

592606
#[inline(always)]
593-
fn adjust_allocation<'b>(
607+
fn adjust_global_allocation<'b>(
594608
_ecx: &InterpCx<$tcx, Self>,
595609
_id: AllocId,
596-
alloc: Cow<'b, Allocation>,
597-
_kind: Option<MemoryKind<Self::MemoryKind>>,
610+
alloc: &'b Allocation,
598611
) -> InterpResult<$tcx, Cow<'b, Allocation<Self::Provenance>>> {
599-
Ok(alloc)
612+
// Overwrite default implementation: no need to adjust anything.
613+
Ok(Cow::Borrowed(alloc))
614+
}
615+
616+
fn init_alloc_extra(
617+
_ecx: &InterpCx<$tcx, Self>,
618+
_id: AllocId,
619+
_kind: MemoryKind<Self::MemoryKind>,
620+
_size: Size,
621+
_align: Align,
622+
) -> InterpResult<$tcx, Self::AllocExtra> {
623+
Ok(())
600624
}
601625

602626
fn extern_static_pointer(

compiler/rustc_const_eval/src/interpret/memory.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
239239

240240
pub fn allocate_raw_ptr(
241241
&mut self,
242-
alloc: Allocation,
242+
alloc: Allocation<M::Provenance, (), M::Bytes>,
243243
kind: MemoryKind<M::MemoryKind>,
244244
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
245245
let id = self.tcx.reserve_alloc_id();
@@ -248,8 +248,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
248248
M::GLOBAL_KIND.map(MemoryKind::Machine),
249249
"dynamically allocating global memory"
250250
);
251-
let alloc = M::adjust_allocation(self, id, Cow::Owned(alloc), Some(kind))?;
252-
self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
251+
// We have set things up so we don't need to call `adjust_from_tcx` here,
252+
// so we avoid copying the entire allocation contents.
253+
let extra = M::init_alloc_extra(self, id, kind, alloc.size(), alloc.align)?;
254+
let alloc = alloc.with_extra(extra);
255+
self.memory.alloc_map.insert(id, (kind, alloc));
253256
M::adjust_alloc_root_pointer(self, Pointer::from(id), Some(kind))
254257
}
255258

@@ -583,11 +586,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
583586
};
584587
M::before_access_global(self.tcx, &self.machine, id, alloc, def_id, is_write)?;
585588
// We got tcx memory. Let the machine initialize its "extra" stuff.
586-
M::adjust_allocation(
589+
M::adjust_global_allocation(
587590
self,
588591
id, // always use the ID we got as input, not the "hidden" one.
589-
Cow::Borrowed(alloc.inner()),
590-
M::GLOBAL_KIND.map(MemoryKind::Machine),
592+
alloc.inner(),
591593
)
592594
}
593595

compiler/rustc_const_eval/src/interpret/operator.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::{bug, span_bug};
99
use rustc_span::symbol::sym;
1010
use tracing::trace;
1111

12-
use super::{err_ub, throw_ub, ImmTy, InterpCx, Machine};
12+
use super::{err_ub, throw_ub, ImmTy, InterpCx, Machine, MemPlaceMeta};
1313

1414
impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
1515
fn three_way_compare<T: Ord>(&self, lhs: T, rhs: T) -> ImmTy<'tcx, M::Provenance> {
@@ -415,11 +415,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
415415
use rustc_middle::mir::UnOp::*;
416416

417417
let layout = val.layout;
418-
let val = val.to_scalar();
419418
trace!("Running unary op {:?}: {:?} ({})", un_op, val, layout.ty);
420419

421420
match layout.ty.kind() {
422421
ty::Bool => {
422+
let val = val.to_scalar();
423423
let val = val.to_bool()?;
424424
let res = match un_op {
425425
Not => !val,
@@ -428,6 +428,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
428428
Ok(ImmTy::from_bool(res, *self.tcx))
429429
}
430430
ty::Float(fty) => {
431+
let val = val.to_scalar();
431432
// No NaN adjustment here, `-` is a bitwise operation!
432433
let res = match (un_op, fty) {
433434
(Neg, FloatTy::F32) => Scalar::from_f32(-val.to_f32()?),
@@ -436,8 +437,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
436437
};
437438
Ok(ImmTy::from_scalar(res, layout))
438439
}
439-
_ => {
440-
assert!(layout.ty.is_integral());
440+
_ if layout.ty.is_integral() => {
441+
let val = val.to_scalar();
441442
let val = val.to_bits(layout.size)?;
442443
let res = match un_op {
443444
Not => self.truncate(!val, layout), // bitwise negation, then truncate
@@ -450,9 +451,28 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
450451
// Truncate to target type.
451452
self.truncate(res, layout)
452453
}
454+
_ => span_bug!(self.cur_span(), "Invalid integer op {:?}", un_op),
453455
};
454456
Ok(ImmTy::from_uint(res, layout))
455457
}
458+
ty::RawPtr(..) => {
459+
assert_eq!(un_op, PtrMetadata);
460+
let (_, meta) = val.to_scalar_and_meta();
461+
Ok(match meta {
462+
MemPlaceMeta::Meta(scalar) => {
463+
let ty = un_op.ty(*self.tcx, val.layout.ty);
464+
let layout = self.layout_of(ty)?;
465+
ImmTy::from_scalar(scalar, layout)
466+
}
467+
MemPlaceMeta::None => {
468+
let unit_layout = self.layout_of(self.tcx.types.unit)?;
469+
ImmTy::uninit(unit_layout)
470+
}
471+
})
472+
}
473+
_ => {
474+
bug!("Unexpected unary op argument {val:?}")
475+
}
456476
}
457477
}
458478
}

0 commit comments

Comments
 (0)