diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/allocation.rs | 43 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/syntax.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/tcx.rs | 26 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs | 2 |
4 files changed, 55 insertions, 23 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 791e87735f4..b0f8a047b82 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -266,19 +266,6 @@ impl AllocRange { // The constructors are all without extra; the extra gets added by a machine hook later. impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> { - /// Creates an allocation from an existing `Bytes` value - this is needed for miri FFI support - pub fn from_raw_bytes(bytes: Bytes, align: Align, mutability: Mutability) -> Self { - let size = Size::from_bytes(bytes.len()); - Self { - bytes, - provenance: ProvenanceMap::new(), - init_mask: InitMask::new(size, true), - align, - mutability, - extra: (), - } - } - /// Creates an allocation initialized by the given bytes pub fn from_bytes<'a>( slice: impl Into<Cow<'a, [u8]>>, @@ -342,18 +329,30 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> { Err(x) => x, } } + + /// Add the extra. + pub fn with_extra<Extra>(self, extra: Extra) -> Allocation<Prov, Extra, Bytes> { + Allocation { + bytes: self.bytes, + provenance: self.provenance, + init_mask: self.init_mask, + align: self.align, + mutability: self.mutability, + extra, + } + } } impl Allocation { /// Adjust allocation from the ones in `tcx` to a custom Machine instance - /// with a different `Provenance`, `Extra` and `Byte` type. - pub fn adjust_from_tcx<Prov: Provenance, Extra, Bytes: AllocBytes, Err>( - self, + /// with a different `Provenance` and `Byte` type. + pub fn adjust_from_tcx<Prov: Provenance, Bytes: AllocBytes, Err>( + &self, cx: &impl HasDataLayout, - extra: Extra, mut adjust_ptr: impl FnMut(Pointer<CtfeProvenance>) -> Result<Pointer<Prov>, Err>, - ) -> Result<Allocation<Prov, Extra, Bytes>, Err> { - let mut bytes = self.bytes; + ) -> Result<Allocation<Prov, (), Bytes>, Err> { + // Copy the data. + let mut bytes = Bytes::from_bytes(Cow::Borrowed(&*self.bytes), self.align); // Adjust provenance of pointers stored in this allocation. let mut new_provenance = Vec::with_capacity(self.provenance.ptrs().len()); let ptr_size = cx.data_layout().pointer_size.bytes_usize(); @@ -369,12 +368,12 @@ impl Allocation { } // Create allocation. Ok(Allocation { - bytes: AllocBytes::from_bytes(Cow::Owned(Vec::from(bytes)), self.align), + bytes, provenance: ProvenanceMap::from_presorted_ptrs(new_provenance), - init_mask: self.init_mask, + init_mask: self.init_mask.clone(), align: self.align, mutability: self.mutability, - extra, + extra: self.extra, }) } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 2d485211433..ebe77a1abfd 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1434,6 +1434,13 @@ pub enum UnOp { Not, /// The `-` operator for negation Neg, + /// Get the metadata `M` from a `*const/mut impl Pointee<Metadata = M>`. + /// + /// For example, this will give a `()` from `*const i32`, a `usize` from + /// `*mut [u8]`, or a pointer to a vtable from a `*const dyn Foo`. + /// + /// Allowed only in [`MirPhase::Runtime`]; earlier it's an intrinsic. + PtrMetadata, } #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)] diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index a122cffdb87..126387db1d9 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -180,7 +180,10 @@ impl<'tcx> Rvalue<'tcx> { let rhs_ty = rhs.ty(local_decls, tcx); op.ty(tcx, lhs_ty, rhs_ty) } - Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx), + Rvalue::UnaryOp(op, ref operand) => { + let arg_ty = operand.ty(local_decls, tcx); + op.ty(tcx, arg_ty) + } Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx), Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => { tcx.types.usize @@ -282,6 +285,27 @@ impl<'tcx> BinOp { } } +impl<'tcx> UnOp { + pub fn ty(&self, tcx: TyCtxt<'tcx>, arg_ty: Ty<'tcx>) -> Ty<'tcx> { + match self { + UnOp::Not | UnOp::Neg => arg_ty, + UnOp::PtrMetadata => { + let pointee_ty = arg_ty + .builtin_deref(true) + .unwrap_or_else(|| bug!("PtrMetadata of non-dereferenceable ty {arg_ty:?}")); + if pointee_ty.is_trivially_sized(tcx) { + tcx.types.unit + } else { + let Some(metadata_def_id) = tcx.lang_items().metadata_type() else { + bug!("No metadata_type lang item while looking at {arg_ty:?}") + }; + Ty::new_projection(tcx, metadata_def_id, [pointee_ty]) + } + } + } + } +} + impl BorrowKind { pub fn to_mutbl_lossy(self) -> hir::Mutability { match self { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3c0f2578284..83790db9926 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1579,8 +1579,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let formatted_op = match op { UnOp::Not => "!", UnOp::Neg => "-", + UnOp::PtrMetadata => "PtrMetadata", }; let parenthesized = match ct.kind() { + _ if op == UnOp::PtrMetadata => true, ty::ConstKind::Expr(Expr::UnOp(c_op, ..)) => c_op != op, ty::ConstKind::Expr(_) => true, _ => false, |
