diff options
| author | Scott McMurray <scottmcm@users.noreply.github.com> | 2024-04-21 16:11:01 -0700 |
|---|---|---|
| committer | Scott McMurray <scottmcm@users.noreply.github.com> | 2024-05-28 09:28:51 -0700 |
| commit | 459ce3f6bb5d8827835ed9b9f916eb189420b38a (patch) | |
| tree | dac17e010317dc8ca899361aa9d0904c3ce3eeb7 /compiler/rustc_middle | |
| parent | 7717a306b2678ba9ece19b723c76a6b3a89ba931 (diff) | |
| download | rust-459ce3f6bb5d8827835ed9b9f916eb189420b38a.tar.gz rust-459ce3f6bb5d8827835ed9b9f916eb189420b38a.zip | |
Add an intrinsic for `ptr::metadata`
Diffstat (limited to 'compiler/rustc_middle')
| -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 |
3 files changed, 34 insertions, 1 deletions
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, |
