Add AggregateKind::RawPtr
and enough support to compile
This commit is contained in:
parent
70df9d9a13
commit
e6b2b764ec
11 changed files with 84 additions and 3 deletions
|
@ -1315,7 +1315,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
AggregateKind::Adt(..)
|
AggregateKind::Adt(..)
|
||||||
| AggregateKind::Array(..)
|
| AggregateKind::Array(..)
|
||||||
| AggregateKind::Tuple { .. } => (),
|
| AggregateKind::Tuple { .. }
|
||||||
|
| AggregateKind::RawPtr(..) => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
for operand in operands {
|
for operand in operands {
|
||||||
|
|
|
@ -1921,7 +1921,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AggregateKind::Array(ty) => Ok(ty),
|
AggregateKind::Array(ty) => Ok(ty),
|
||||||
AggregateKind::Tuple => {
|
AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
|
||||||
unreachable!("This should have been covered in check_rvalues");
|
unreachable!("This should have been covered in check_rvalues");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2518,6 +2518,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
AggregateKind::Closure(_, _) => None,
|
AggregateKind::Closure(_, _) => None,
|
||||||
AggregateKind::Coroutine(_, _) => None,
|
AggregateKind::Coroutine(_, _) => None,
|
||||||
AggregateKind::CoroutineClosure(_, _) => None,
|
AggregateKind::CoroutineClosure(_, _) => None,
|
||||||
|
AggregateKind::RawPtr(_, _) => None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2539,6 +2540,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let AggregateKind::RawPtr(..) = aggregate_kind {
|
||||||
|
bug!("RawPtr should only be in runtime MIR");
|
||||||
|
}
|
||||||
|
|
||||||
for (i, operand) in operands.iter_enumerated() {
|
for (i, operand) in operands.iter_enumerated() {
|
||||||
let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
|
let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
|
||||||
Ok(field_ty) => field_ty,
|
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())
|
(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, _) => {
|
Rvalue::Ref(_, BorrowKind::Fake, _) => {
|
||||||
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
|
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
|
||||||
|
|
|
@ -1094,6 +1094,15 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
||||||
|
|
||||||
struct_fmt.finish()
|
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>),
|
Closure(DefId, GenericArgsRef<'tcx>),
|
||||||
Coroutine(DefId, GenericArgsRef<'tcx>),
|
Coroutine(DefId, GenericArgsRef<'tcx>),
|
||||||
CoroutineClosure(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)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
|
||||||
|
|
|
@ -206,6 +206,7 @@ impl<'tcx> Rvalue<'tcx> {
|
||||||
AggregateKind::CoroutineClosure(did, args) => {
|
AggregateKind::CoroutineClosure(did, args) => {
|
||||||
Ty::new_coroutine_closure(tcx, 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::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),
|
||||||
Rvalue::CopyForDeref(ref place) => place.ty(local_decls, 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);
|
self.visit_args(coroutine_closure_args, location);
|
||||||
}
|
}
|
||||||
|
AggregateKind::RawPtr(ty, _) => {
|
||||||
|
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for operand in operands {
|
for operand in operands {
|
||||||
|
|
|
@ -885,6 +885,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
AggregateKind::Adt(did, ..) => tcx.def_kind(did) != DefKind::Enum,
|
AggregateKind::Adt(did, ..) => tcx.def_kind(did) != DefKind::Enum,
|
||||||
// Coroutines are never ZST, as they at least contain the implicit states.
|
// Coroutines are never ZST, as they at least contain the implicit states.
|
||||||
AggregateKind::Coroutine(..) => false,
|
AggregateKind::Coroutine(..) => false,
|
||||||
|
AggregateKind::RawPtr(..) => bug!("MIR for RawPtr aggregate must have 2 fields"),
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_zst {
|
if is_zst {
|
||||||
|
@ -910,6 +911,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
}
|
}
|
||||||
// Do not track unions.
|
// Do not track unions.
|
||||||
AggregateKind::Adt(_, _, _, _, Some(_)) => return None,
|
AggregateKind::Adt(_, _, _, _, Some(_)) => return None,
|
||||||
|
// FIXME: Do the extra work to GVN `from_raw_parts`
|
||||||
|
AggregateKind::RawPtr(..) => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let fields: Option<Vec<_>> = fields
|
let fields: Option<Vec<_>> = fields
|
||||||
|
|
|
@ -603,6 +603,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
AggregateKind::Adt(_, variant, _, _, _) => variant,
|
AggregateKind::Adt(_, variant, _, _, _) => variant,
|
||||||
AggregateKind::Array(_)
|
AggregateKind::Array(_)
|
||||||
| AggregateKind::Tuple
|
| AggregateKind::Tuple
|
||||||
|
| AggregateKind::RawPtr(_, _)
|
||||||
| AggregateKind::Closure(_, _)
|
| AggregateKind::Closure(_, _)
|
||||||
| AggregateKind::Coroutine(_, _)
|
| AggregateKind::Coroutine(_, _)
|
||||||
| AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO,
|
| AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO,
|
||||||
|
|
|
@ -543,6 +543,9 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
|
||||||
mir::AggregateKind::CoroutineClosure(..) => {
|
mir::AggregateKind::CoroutineClosure(..) => {
|
||||||
todo!("FIXME(async_closures): Lower these to SMIR")
|
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) => {
|
AggregateKind::Coroutine(def, ref args, mov) => {
|
||||||
Ok(Ty::new_coroutine(def, args.clone(), 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::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)),
|
||||||
Rvalue::CopyForDeref(place) => place.ty(locals),
|
Rvalue::CopyForDeref(place) => place.ty(locals),
|
||||||
|
@ -617,6 +618,7 @@ pub enum AggregateKind {
|
||||||
Closure(ClosureDef, GenericArgs),
|
Closure(ClosureDef, GenericArgs),
|
||||||
// FIXME(stable_mir): Movability here is redundant
|
// FIXME(stable_mir): Movability here is redundant
|
||||||
Coroutine(CoroutineDef, GenericArgs, Movability),
|
Coroutine(CoroutineDef, GenericArgs, Movability),
|
||||||
|
RawPtr(Ty, Mutability),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue