1
Fork 0

Rollup merge of #124251 - scottmcm:unop-ptr-metadata, r=oli-obk

Add an intrinsic for `ptr::metadata`

The follow-up to #123840, so we can remove `PtrComponents` and `PtrRepr` from libcore entirely (well, after a bootstrap update).

As discussed in <https://rust-lang.zulipchat.com/#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/.60ptr_metadata.60.20in.20MIR/near/435637808>, this introduces `UnOp::PtrMetadata` taking a raw pointer and returning the associated metadata value.

By no longer going through a `union`, this should also help future PRs better optimize pointer operations.

r? ``@oli-obk``
This commit is contained in:
许杰友 Jieyou Xu (Joe) 2024-05-29 03:25:07 +01:00 committed by GitHub
commit 2d3b1e014b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
42 changed files with 600 additions and 53 deletions

View file

@ -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)]

View file

@ -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 {

View file

@ -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,