Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
{
// That next check is expensive, that's why we have all the guards above.
let is_immutable = ty.is_freeze(*ecx.tcx, ecx.typing_env());
let place = ecx.ref_to_mplace(val)?;
let place = ecx.imm_ptr_to_mplace(val)?;
let new_place = if is_immutable {
place.map_provenance(CtfeProvenance::as_immutable)
} else {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/const_eval/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
None => Cow::Owned(idx.to_string()), // For tuples
};
let name_place = self.allocate_str_dedup(&name)?;
let ptr = self.mplace_to_ref(&name_place)?;
let ptr = self.mplace_to_imm_ptr(&name_place, None)?;
self.write_immediate(*ptr, &field_place)?
}
sym::ty => {
Expand Down Expand Up @@ -444,7 +444,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
other_abi => {
let (variant, variant_place) = self.downcast(&field_place, sym::Named)?;
let str_place = self.allocate_str_dedup(other_abi.as_str())?;
let str_ref = self.mplace_to_ref(&str_place)?;
let str_ref = self.mplace_to_imm_ptr(&str_place, None)?;
let payload = self.project_field(&variant_place, FieldIdx::ZERO)?;
self.write_immediate(*str_ref, &payload)?;
self.write_discriminant(variant, &field_place)?;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/type_info/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
match field_def.name {
sym::name => {
let name_place = self.allocate_str_dedup(variant_def.name.as_str())?;
let ptr = self.mplace_to_ref(&name_place)?;
let ptr = self.mplace_to_imm_ptr(&name_place, None)?;
self.write_immediate(*ptr, &field_place)?
}
sym::fields => {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/interpret/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// actually access memory to resolve this method.
// Also see <https://github.com/rust-lang/miri/issues/2786>.
let val = self.read_immediate(&receiver)?;
break self.ref_to_mplace(&val)?;
break self.imm_ptr_to_mplace(&val)?;
}
ty::Dynamic(..) => break receiver.assert_mem_place(), // no immediate unsized values
_ => {
Expand Down Expand Up @@ -877,7 +877,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// then dispatches that to the normal call machinery. However, our call machinery currently
// only supports calling `VtblEntry::Method`; it would choke on a `MetadataDropInPlace`. So
// instead we do the virtual call stuff ourselves. It's easier here than in `eval_fn_call`
// since we can just get a place of the underlying type and use `mplace_to_ref`.
// since we can just get a place of the underlying type and use `mplace_to_imm_ptr`.
let place = match place.layout.ty.kind() {
ty::Dynamic(data, _) => {
// Dropping a trait object. Need to find actual drop fn.
Expand All @@ -898,7 +898,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
};
let fn_abi = self.fn_abi_of_instance_no_deduced_attrs(instance, ty::List::empty())?;

let arg = self.mplace_to_ref(&place)?;
let arg = self.mplace_to_imm_ptr(&place, None)?;
let ret = MPlaceTy::fake_alloc_zst(self.layout_of(self.tcx.types.unit)?);

self.init_fn_call(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
sym::align_of_val | sym::size_of_val => {
// Avoid `deref_pointer` -- this is not a deref, the ptr does not have to be
// dereferenceable!
let place = self.ref_to_mplace(&self.read_immediate(&args[0])?)?;
let place = self.imm_ptr_to_mplace(&self.read_immediate(&args[0])?)?;
let (size, align) = self
.size_and_align_of_val(&place)?
.ok_or_else(|| err_unsup_format!("`extern type` does not have known layout"))?;
Expand Down
28 changes: 19 additions & 9 deletions compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,36 +417,46 @@ where
self.ptr_with_meta_to_mplace(ptr, MemPlaceMeta::None, layout, /*unaligned*/ true)
}

/// Take a value, which represents a (thin or wide) reference, and make it a place.
/// Alignment is just based on the type. This is the inverse of `mplace_to_ref()`.
/// Take a value, which represents a (thin or wide) pointer, and make it a place.
/// Alignment is just based on the type. This is the inverse of `mplace_to_imm_ptr()`.
///
/// Only call this if you are sure the place is "valid" (aligned and inbounds), or do not
/// want to ever use the place for memory access!
/// Generally prefer `deref_pointer`.
pub fn ref_to_mplace(
pub fn imm_ptr_to_mplace(
&self,
val: &ImmTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
let pointee_type =
val.layout.ty.builtin_deref(true).expect("`ref_to_mplace` called on non-ptr type");
val.layout.ty.builtin_deref(true).expect("`imm_ptr_to_mplace` called on non-ptr type");
let layout = self.layout_of(pointee_type)?;
let (ptr, meta) = val.to_scalar_and_meta();

// `ref_to_mplace` is called on raw pointers even if they don't actually get dereferenced;
// `imm_ptr_to_mplace` is called on raw pointers even if they don't actually get dereferenced;
// we hence can't call `size_and_align_of` since that asserts more validity than we want.
let ptr = ptr.to_pointer(self)?;
interp_ok(self.ptr_with_meta_to_mplace(ptr, meta, layout, /*unaligned*/ false))
}

/// Turn a mplace into a (thin or wide) mutable raw pointer, pointing to the same space.
///
/// `align` information is lost!
/// This is the inverse of `ref_to_mplace`.
pub fn mplace_to_ref(
/// This is the inverse of `imm_ptr_to_mplace`.
///
/// If `ptr_ty` is provided, the resulting pointer will be of that type. Otherwise, it defaults to `*mut _`.
/// `ptr_ty` must be a type with builtin deref which derefs to the type of `mplace` (`mplace.layout.ty`).
pub fn mplace_to_imm_ptr(
&self,
mplace: &MPlaceTy<'tcx, M::Provenance>,
ptr_ty: Option<Ty<'tcx>>,
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
let imm = mplace.mplace.to_ref(self);
let layout = self.layout_of(Ty::new_mut_ptr(self.tcx.tcx, mplace.layout.ty))?;

let ptr_ty = ptr_ty
.inspect(|t| assert_eq!(t.builtin_deref(true), Some(mplace.layout.ty)))
.unwrap_or_else(|| Ty::new_mut_ptr(self.tcx.tcx, mplace.layout.ty));

let layout = self.layout_of(ptr_ty)?;
interp_ok(ImmTy::from_immediate(imm, layout))
}

Expand All @@ -467,7 +477,7 @@ where
let val = self.read_immediate(src)?;
trace!("deref to {} on {:?}", val.layout.ty, *val);

let mplace = self.ref_to_mplace(&val)?;
let mplace = self.imm_ptr_to_mplace(&val)?;
interp_ok(mplace)
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
self.add_data_range_place(val);
}
// Now turn it into a place.
self.ecx.ref_to_mplace(&imm)
self.ecx.imm_ptr_to_mplace(&imm)
}

fn check_wide_ptr_meta(
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/mem/maybe_dangling.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![unstable(feature = "maybe_dangling", issue = "118166")]

use crate::marker::StructuralPartialEq;
use crate::{mem, ptr};

/// Allows wrapped [references] and [boxes] to dangle.
Expand Down Expand Up @@ -109,3 +110,5 @@ impl<P: ?Sized> MaybeDangling<P> {
x
}
}

impl<T: ?Sized> StructuralPartialEq for MaybeDangling<T> {}
2 changes: 1 addition & 1 deletion src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
info: RetagInfo, // diagnostics info about this retag
) -> InterpResult<'tcx, ImmTy<'tcx>> {
let this = self.eval_context_mut();
let place = this.ref_to_mplace(val)?;
let place = this.imm_ptr_to_mplace(val)?;
let new_place = this.sb_retag_place(&place, new_perm, info)?;
interp_ok(ImmTy::from_immediate(new_place.to_ref(this), val.layout))
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
new_perm: NewPermission,
) -> InterpResult<'tcx, ImmTy<'tcx>> {
let this = self.eval_context_mut();
let place = this.ref_to_mplace(val)?;
let place = this.imm_ptr_to_mplace(val)?;
let new_place = this.tb_retag_place(&place, new_perm)?;
interp_ok(ImmTy::from_immediate(new_place.to_ref(this), val.layout))
}
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/src/shims/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.call_function(
panic,
ExternAbi::Rust,
&[this.mplace_to_ref(&msg)?],
&[this.mplace_to_imm_ptr(&msg, None)?],
None,
ReturnContinuation::Goto { ret: None, unwind },
)
Expand All @@ -39,7 +39,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.call_function(
panic,
ExternAbi::Rust,
&[this.mplace_to_ref(&msg)?],
&[this.mplace_to_imm_ptr(&msg, None)?],
None,
ReturnContinuation::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
)
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/consts/manually_drop_structural_eq.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Check that `ManuallyDrop` types can be used as a constant when matching.
// I.e. that `ManuallyDrop` implements `StructuralPartialEq`.
//
// Regression test for <https://github.com/rust-lang/rust/issues/154890>.
//
//@ check-pass
use std::mem::ManuallyDrop;

fn main() {
const X: ManuallyDrop<u32> = ManuallyDrop::new(1);

match ManuallyDrop::new(1) {
X => println!("blah"),
_ => println!("bleh"),
}
}
Loading