mirror of https://github.com/rust-lang/rust.git
Add `AggregateKind::RawPtr` and enough support to compile
This commit is contained in:
parent
70df9d9a13
commit
e6b2b764ec
|
@ -1315,7 +1315,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
AggregateKind::Adt(..)
|
||||
| AggregateKind::Array(..)
|
||||
| AggregateKind::Tuple { .. } => (),
|
||||
| AggregateKind::Tuple { .. }
|
||||
| AggregateKind::RawPtr(..) => (),
|
||||
}
|
||||
|
||||
for operand in operands {
|
||||
|
|
|
@ -1921,7 +1921,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
AggregateKind::Array(ty) => Ok(ty),
|
||||
AggregateKind::Tuple => {
|
||||
AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
|
||||
unreachable!("This should have been covered in check_rvalues");
|
||||
}
|
||||
}
|
||||
|
@ -2518,6 +2518,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
AggregateKind::Closure(_, _) => None,
|
||||
AggregateKind::Coroutine(_, _) => None,
|
||||
AggregateKind::CoroutineClosure(_, _) => None,
|
||||
AggregateKind::RawPtr(_, _) => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -2539,6 +2540,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
if let AggregateKind::RawPtr(..) = aggregate_kind {
|
||||
bug!("RawPtr should only be in runtime MIR");
|
||||
}
|
||||
|
||||
for (i, operand) in operands.iter_enumerated() {
|
||||
let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
|
||||
Ok(field_ty) => field_ty,
|
||||
|
@ -2757,7 +2762,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
),
|
||||
),
|
||||
|
||||
AggregateKind::Array(_) | AggregateKind::Tuple => {
|
||||
AggregateKind::Array(_) | AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
|
||||
(CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty())
|
||||
}
|
||||
};
|
||||
|
|
|
@ -923,6 +923,44 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
AggregateKind::RawPtr(pointee_ty, mutability) => {
|
||||
if !matches!(self.mir_phase, MirPhase::Runtime(_)) {
|
||||
// It would probably be fine to support this in earlier phases,
|
||||
// but at the time of writing it's only ever introduced from intrinsic lowering,
|
||||
// so earlier things just `bug!` on it.
|
||||
self.fail(location, "RawPtr should be in runtime MIR only");
|
||||
}
|
||||
|
||||
if fields.len() != 2 {
|
||||
self.fail(location, "raw pointer aggregate must have 2 fields");
|
||||
} else {
|
||||
let data_ptr_ty = fields.raw[0].ty(self.body, self.tcx);
|
||||
let metadata_ty = fields.raw[1].ty(self.body, self.tcx);
|
||||
if let ty::RawPtr(in_pointee, in_mut) = data_ptr_ty.kind() {
|
||||
if *in_mut != mutability {
|
||||
self.fail(location, "input and output mutability must match");
|
||||
}
|
||||
|
||||
// FIXME: check `Thin` instead of `Sized`
|
||||
if !in_pointee.is_sized(self.tcx, self.param_env) {
|
||||
self.fail(location, "input pointer must be thin");
|
||||
}
|
||||
} else {
|
||||
self.fail(location, "first operand to raw pointer aggregate must be a raw pointer");
|
||||
}
|
||||
|
||||
// FIXME: Check metadata more generally
|
||||
if pointee_ty.is_slice() {
|
||||
if !self.mir_assign_valid_types(metadata_ty, self.tcx.types.usize) {
|
||||
self.fail(location, "slice metadata must be usize");
|
||||
}
|
||||
} else if pointee_ty.is_sized(self.tcx, self.param_env) {
|
||||
if metadata_ty != self.tcx.types.unit {
|
||||
self.fail(location, "metadata for pointer-to-thin must be unit");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Rvalue::Ref(_, BorrowKind::Fake, _) => {
|
||||
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
|
||||
|
|
|
@ -1094,6 +1094,15 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
|||
|
||||
struct_fmt.finish()
|
||||
}),
|
||||
|
||||
AggregateKind::RawPtr(pointee_ty, mutability) => {
|
||||
let kind_str = match mutability {
|
||||
Mutability::Mut => "mut",
|
||||
Mutability::Not => "const",
|
||||
};
|
||||
with_no_trimmed_paths!(write!(fmt, "*{kind_str} {pointee_ty} from "))?;
|
||||
fmt_tuple(fmt, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1351,6 +1351,21 @@ pub enum AggregateKind<'tcx> {
|
|||
Closure(DefId, GenericArgsRef<'tcx>),
|
||||
Coroutine(DefId, GenericArgsRef<'tcx>),
|
||||
CoroutineClosure(DefId, GenericArgsRef<'tcx>),
|
||||
|
||||
/// Construct a raw pointer from the data pointer and metadata.
|
||||
///
|
||||
/// The `Ty` here is the type of the *pointee*, not the pointer itself.
|
||||
/// The `Mutability` indicates whether this produces a `*const` or `*mut`.
|
||||
///
|
||||
/// The [`Rvalue::Aggregate`] operands for thus must be
|
||||
///
|
||||
/// 0. A raw pointer of matching mutability with any [`core::ptr::Thin`] pointee
|
||||
/// 1. A value of the appropriate [`core::ptr::Pointee::Metadata`] type
|
||||
///
|
||||
/// *Both* operands must always be included, even the unit value if this is
|
||||
/// creating a thin pointer. If you're just converting between thin pointers,
|
||||
/// you may want an [`Rvalue::Cast`] with [`CastKind::PtrToPtr`] instead.
|
||||
RawPtr(Ty<'tcx>, Mutability),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
|
||||
|
|
|
@ -206,6 +206,7 @@ impl<'tcx> Rvalue<'tcx> {
|
|||
AggregateKind::CoroutineClosure(did, args) => {
|
||||
Ty::new_coroutine_closure(tcx, did, args)
|
||||
}
|
||||
AggregateKind::RawPtr(ty, mutability) => Ty::new_ptr(tcx, ty, mutability),
|
||||
},
|
||||
Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),
|
||||
Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty,
|
||||
|
|
|
@ -751,6 +751,9 @@ macro_rules! make_mir_visitor {
|
|||
) => {
|
||||
self.visit_args(coroutine_closure_args, location);
|
||||
}
|
||||
AggregateKind::RawPtr(ty, _) => {
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
}
|
||||
|
||||
for operand in operands {
|
||||
|
|
|
@ -885,6 +885,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
AggregateKind::Adt(did, ..) => tcx.def_kind(did) != DefKind::Enum,
|
||||
// Coroutines are never ZST, as they at least contain the implicit states.
|
||||
AggregateKind::Coroutine(..) => false,
|
||||
AggregateKind::RawPtr(..) => bug!("MIR for RawPtr aggregate must have 2 fields"),
|
||||
};
|
||||
|
||||
if is_zst {
|
||||
|
@ -910,6 +911,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
}
|
||||
// Do not track unions.
|
||||
AggregateKind::Adt(_, _, _, _, Some(_)) => return None,
|
||||
// FIXME: Do the extra work to GVN `from_raw_parts`
|
||||
AggregateKind::RawPtr(..) => return None,
|
||||
};
|
||||
|
||||
let fields: Option<Vec<_>> = fields
|
||||
|
|
|
@ -603,6 +603,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
AggregateKind::Adt(_, variant, _, _, _) => variant,
|
||||
AggregateKind::Array(_)
|
||||
| AggregateKind::Tuple
|
||||
| AggregateKind::RawPtr(_, _)
|
||||
| AggregateKind::Closure(_, _)
|
||||
| AggregateKind::Coroutine(_, _)
|
||||
| AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO,
|
||||
|
|
|
@ -543,6 +543,9 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
|
|||
mir::AggregateKind::CoroutineClosure(..) => {
|
||||
todo!("FIXME(async_closures): Lower these to SMIR")
|
||||
}
|
||||
mir::AggregateKind::RawPtr(ty, mutability) => {
|
||||
stable_mir::mir::AggregateKind::RawPtr(ty.stable(tables), mutability.stable(tables))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -602,6 +602,7 @@ impl Rvalue {
|
|||
AggregateKind::Coroutine(def, ref args, mov) => {
|
||||
Ok(Ty::new_coroutine(def, args.clone(), mov))
|
||||
}
|
||||
AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)),
|
||||
},
|
||||
Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)),
|
||||
Rvalue::CopyForDeref(place) => place.ty(locals),
|
||||
|
@ -617,6 +618,7 @@ pub enum AggregateKind {
|
|||
Closure(ClosureDef, GenericArgs),
|
||||
// FIXME(stable_mir): Movability here is redundant
|
||||
Coroutine(CoroutineDef, GenericArgs, Movability),
|
||||
RawPtr(Ty, Mutability),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
|
|
Loading…
Reference in New Issue