Skip to content

Commit e6b2b76

Browse files
committed
Add AggregateKind::RawPtr and enough support to compile
1 parent 70df9d9 commit e6b2b76

File tree

11 files changed

+84
-3
lines changed

11 files changed

+84
-3
lines changed

compiler/rustc_borrowck/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1315,7 +1315,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
13151315
}
13161316
AggregateKind::Adt(..)
13171317
| AggregateKind::Array(..)
1318-
| AggregateKind::Tuple { .. } => (),
1318+
| AggregateKind::Tuple { .. }
1319+
| AggregateKind::RawPtr(..) => (),
13191320
}
13201321

13211322
for operand in operands {

compiler/rustc_borrowck/src/type_check/mod.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1921,7 +1921,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19211921
}
19221922
}
19231923
AggregateKind::Array(ty) => Ok(ty),
1924-
AggregateKind::Tuple => {
1924+
AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
19251925
unreachable!("This should have been covered in check_rvalues");
19261926
}
19271927
}
@@ -2518,6 +2518,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
25182518
AggregateKind::Closure(_, _) => None,
25192519
AggregateKind::Coroutine(_, _) => None,
25202520
AggregateKind::CoroutineClosure(_, _) => None,
2521+
AggregateKind::RawPtr(_, _) => None,
25212522
},
25222523
}
25232524
}
@@ -2539,6 +2540,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
25392540
return;
25402541
}
25412542

2543+
if let AggregateKind::RawPtr(..) = aggregate_kind {
2544+
bug!("RawPtr should only be in runtime MIR");
2545+
}
2546+
25422547
for (i, operand) in operands.iter_enumerated() {
25432548
let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
25442549
Ok(field_ty) => field_ty,
@@ -2757,7 +2762,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
27572762
),
27582763
),
27592764

2760-
AggregateKind::Array(_) | AggregateKind::Tuple => {
2765+
AggregateKind::Array(_) | AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
27612766
(CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty())
27622767
}
27632768
};

compiler/rustc_const_eval/src/transform/validate.rs

+38
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,44 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
923923
}
924924
}
925925
}
926+
AggregateKind::RawPtr(pointee_ty, mutability) => {
927+
if !matches!(self.mir_phase, MirPhase::Runtime(_)) {
928+
// It would probably be fine to support this in earlier phases,
929+
// but at the time of writing it's only ever introduced from intrinsic lowering,
930+
// so earlier things just `bug!` on it.
931+
self.fail(location, "RawPtr should be in runtime MIR only");
932+
}
933+
934+
if fields.len() != 2 {
935+
self.fail(location, "raw pointer aggregate must have 2 fields");
936+
} else {
937+
let data_ptr_ty = fields.raw[0].ty(self.body, self.tcx);
938+
let metadata_ty = fields.raw[1].ty(self.body, self.tcx);
939+
if let ty::RawPtr(in_pointee, in_mut) = data_ptr_ty.kind() {
940+
if *in_mut != mutability {
941+
self.fail(location, "input and output mutability must match");
942+
}
943+
944+
// FIXME: check `Thin` instead of `Sized`
945+
if !in_pointee.is_sized(self.tcx, self.param_env) {
946+
self.fail(location, "input pointer must be thin");
947+
}
948+
} else {
949+
self.fail(location, "first operand to raw pointer aggregate must be a raw pointer");
950+
}
951+
952+
// FIXME: Check metadata more generally
953+
if pointee_ty.is_slice() {
954+
if !self.mir_assign_valid_types(metadata_ty, self.tcx.types.usize) {
955+
self.fail(location, "slice metadata must be usize");
956+
}
957+
} else if pointee_ty.is_sized(self.tcx, self.param_env) {
958+
if metadata_ty != self.tcx.types.unit {
959+
self.fail(location, "metadata for pointer-to-thin must be unit");
960+
}
961+
}
962+
}
963+
}
926964
},
927965
Rvalue::Ref(_, BorrowKind::Fake, _) => {
928966
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {

compiler/rustc_middle/src/mir/pretty.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,15 @@ impl<'tcx> Debug for Rvalue<'tcx> {
10941094

10951095
struct_fmt.finish()
10961096
}),
1097+
1098+
AggregateKind::RawPtr(pointee_ty, mutability) => {
1099+
let kind_str = match mutability {
1100+
Mutability::Mut => "mut",
1101+
Mutability::Not => "const",
1102+
};
1103+
with_no_trimmed_paths!(write!(fmt, "*{kind_str} {pointee_ty} from "))?;
1104+
fmt_tuple(fmt, "")
1105+
}
10971106
}
10981107
}
10991108

compiler/rustc_middle/src/mir/syntax.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,21 @@ pub enum AggregateKind<'tcx> {
13511351
Closure(DefId, GenericArgsRef<'tcx>),
13521352
Coroutine(DefId, GenericArgsRef<'tcx>),
13531353
CoroutineClosure(DefId, GenericArgsRef<'tcx>),
1354+
1355+
/// Construct a raw pointer from the data pointer and metadata.
1356+
///
1357+
/// The `Ty` here is the type of the *pointee*, not the pointer itself.
1358+
/// The `Mutability` indicates whether this produces a `*const` or `*mut`.
1359+
///
1360+
/// The [`Rvalue::Aggregate`] operands for thus must be
1361+
///
1362+
/// 0. A raw pointer of matching mutability with any [`core::ptr::Thin`] pointee
1363+
/// 1. A value of the appropriate [`core::ptr::Pointee::Metadata`] type
1364+
///
1365+
/// *Both* operands must always be included, even the unit value if this is
1366+
/// creating a thin pointer. If you're just converting between thin pointers,
1367+
/// you may want an [`Rvalue::Cast`] with [`CastKind::PtrToPtr`] instead.
1368+
RawPtr(Ty<'tcx>, Mutability),
13541369
}
13551370

13561371
#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]

compiler/rustc_middle/src/mir/tcx.rs

+1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ impl<'tcx> Rvalue<'tcx> {
206206
AggregateKind::CoroutineClosure(did, args) => {
207207
Ty::new_coroutine_closure(tcx, did, args)
208208
}
209+
AggregateKind::RawPtr(ty, mutability) => Ty::new_ptr(tcx, ty, mutability),
209210
},
210211
Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),
211212
Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty,

compiler/rustc_middle/src/mir/visit.rs

+3
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,9 @@ macro_rules! make_mir_visitor {
751751
) => {
752752
self.visit_args(coroutine_closure_args, location);
753753
}
754+
AggregateKind::RawPtr(ty, _) => {
755+
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
756+
}
754757
}
755758

756759
for operand in operands {

compiler/rustc_mir_transform/src/gvn.rs

+3
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
885885
AggregateKind::Adt(did, ..) => tcx.def_kind(did) != DefKind::Enum,
886886
// Coroutines are never ZST, as they at least contain the implicit states.
887887
AggregateKind::Coroutine(..) => false,
888+
AggregateKind::RawPtr(..) => bug!("MIR for RawPtr aggregate must have 2 fields"),
888889
};
889890

890891
if is_zst {
@@ -910,6 +911,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
910911
}
911912
// Do not track unions.
912913
AggregateKind::Adt(_, _, _, _, Some(_)) => return None,
914+
// FIXME: Do the extra work to GVN `from_raw_parts`
915+
AggregateKind::RawPtr(..) => return None,
913916
};
914917

915918
let fields: Option<Vec<_>> = fields

compiler/rustc_mir_transform/src/known_panics_lint.rs

+1
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
603603
AggregateKind::Adt(_, variant, _, _, _) => variant,
604604
AggregateKind::Array(_)
605605
| AggregateKind::Tuple
606+
| AggregateKind::RawPtr(_, _)
606607
| AggregateKind::Closure(_, _)
607608
| AggregateKind::Coroutine(_, _)
608609
| AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO,

compiler/rustc_smir/src/rustc_smir/convert/mir.rs

+3
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,9 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
543543
mir::AggregateKind::CoroutineClosure(..) => {
544544
todo!("FIXME(async_closures): Lower these to SMIR")
545545
}
546+
mir::AggregateKind::RawPtr(ty, mutability) => {
547+
stable_mir::mir::AggregateKind::RawPtr(ty.stable(tables), mutability.stable(tables))
548+
}
546549
}
547550
}
548551
}

compiler/stable_mir/src/mir/body.rs

+2
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ impl Rvalue {
602602
AggregateKind::Coroutine(def, ref args, mov) => {
603603
Ok(Ty::new_coroutine(def, args.clone(), mov))
604604
}
605+
AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)),
605606
},
606607
Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)),
607608
Rvalue::CopyForDeref(place) => place.ty(locals),
@@ -617,6 +618,7 @@ pub enum AggregateKind {
617618
Closure(ClosureDef, GenericArgs),
618619
// FIXME(stable_mir): Movability here is redundant
619620
Coroutine(CoroutineDef, GenericArgs, Movability),
621+
RawPtr(Ty, Mutability),
620622
}
621623

622624
#[derive(Clone, Debug, Eq, PartialEq)]

0 commit comments

Comments
 (0)