diff options
| author | bors <bors@rust-lang.org> | 2024-04-21 21:08:03 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-04-21 21:08:03 +0000 |
| commit | fb898629a26e4acec59c928ce3ec00a62675d1cc (patch) | |
| tree | ba73dfeeabaa003efb79a37a8cf7ae0de48e6cb5 /compiler | |
| parent | 1b3fba066c21e7c3471fca710783fc1e6546a1ca (diff) | |
| parent | 3315bf961d4d7dfafe3f8b01f892317e4f746861 (diff) | |
| download | rust-fb898629a26e4acec59c928ce3ec00a62675d1cc.tar.gz rust-fb898629a26e4acec59c928ce3ec00a62675d1cc.zip | |
Auto merge of #124241 - matthiaskrgr:rollup-xhu90xr, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #123840 (Add an intrinsic for `ptr::from_raw_parts(_mut)`) - #124224 (cleanup: unnecessary clone during lower generics args) - #124229 (Add gnullvm targets to manifest) - #124231 (remove from reviewers) - #124235 (Move some tests) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
20 files changed, 235 insertions, 10 deletions
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 7fbf4c47ec8..a69b644c4dc 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1315,7 +1315,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } AggregateKind::Adt(..) | AggregateKind::Array(..) - | AggregateKind::Tuple { .. } => (), + | AggregateKind::Tuple { .. } + | AggregateKind::RawPtr(..) => (), } for operand in operands { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 0600a105459..61fa8466674 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -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()) } }; diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index f07421431da..f428c4c7c0d 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -813,6 +813,19 @@ fn codegen_stmt<'tcx>( ); lval.write_cvalue(fx, val); } + Rvalue::Aggregate(ref kind, ref operands) + if matches!(**kind, AggregateKind::RawPtr(..)) => + { + let ty = to_place_and_rval.1.ty(&fx.mir.local_decls, fx.tcx); + let layout = fx.layout_of(fx.monomorphize(ty)); + let [data, meta] = &*operands.raw else { + bug!("RawPtr fields: {operands:?}"); + }; + let data = codegen_operand(fx, data); + let meta = codegen_operand(fx, meta); + let ptr_val = CValue::pointer_from_data_and_meta(data, meta, layout); + lval.write_cvalue(fx, ptr_val); + } Rvalue::Aggregate(ref kind, ref operands) => { let (variant_index, variant_dest, active_field_index) = match **kind { mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => { diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index ad863903cee..8d52fd9d7a8 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -94,6 +94,23 @@ impl<'tcx> CValue<'tcx> { CValue(CValueInner::ByValPair(value, extra), layout) } + /// For `AggregateKind::RawPtr`, create a pointer from its parts. + /// + /// Panics if the `layout` is not a raw pointer. + pub(crate) fn pointer_from_data_and_meta( + data: CValue<'tcx>, + meta: CValue<'tcx>, + layout: TyAndLayout<'tcx>, + ) -> CValue<'tcx> { + assert!(layout.ty.is_unsafe_ptr()); + let inner = match (data.0, meta.0) { + (CValueInner::ByVal(p), CValueInner::ByVal(m)) => CValueInner::ByValPair(p, m), + (p @ CValueInner::ByVal(_), CValueInner::ByRef(..)) if meta.1.is_zst() => p, + _ => bug!("RawPtr operands {data:?} {meta:?}"), + }; + CValue(inner, layout) + } + pub(crate) fn layout(&self) -> TyAndLayout<'tcx> { self.1 } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 6725a6d9e38..7823d4c249a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -9,7 +9,7 @@ use crate::MemFlags; use rustc_hir as hir; use rustc_middle::mir; -use rustc_middle::mir::Operand; +use rustc_middle::mir::{AggregateKind, Operand}; use rustc_middle::ty::cast::{CastTy, IntTy}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, Ty, TyCtxt}; @@ -720,6 +720,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { val: OperandValue::Immediate(static_), layout } } mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand), + mir::Rvalue::Aggregate(box mir::AggregateKind::RawPtr(..), ref fields) => { + let ty = rvalue.ty(self.mir, self.cx.tcx()); + let layout = self.cx.layout_of(self.monomorphize(ty)); + let [data, meta] = &*fields.raw else { + bug!("RawPtr fields: {fields:?}"); + }; + let data = self.codegen_operand(bx, data); + let meta = self.codegen_operand(bx, meta); + match (data.val, meta.val) { + (p @ OperandValue::Immediate(_), OperandValue::ZeroSized) => { + OperandRef { val: p, layout } + } + (OperandValue::Immediate(p), OperandValue::Immediate(m)) => { + OperandRef { val: OperandValue::Pair(p, m), layout } + } + _ => bug!("RawPtr operands {data:?} {meta:?}"), + } + } mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => { // According to `rvalue_creates_operand`, only ZST // aggregate rvalues are allowed to be operands. @@ -1032,6 +1050,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::ThreadLocalRef(_) | mir::Rvalue::Use(..) => // (*) true, + // This always produces a `ty::RawPtr`, so will be Immediate or Pair + mir::Rvalue::Aggregate(box AggregateKind::RawPtr(..), ..) => true, mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => { let ty = rvalue.ty(self.mir, self.cx.tcx()); diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index c3f26da8a79..b29034e991e 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -9,7 +9,9 @@ use rustc_middle::mir; use rustc_middle::ty::layout::LayoutOf; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; -use super::{ImmTy, InterpCx, InterpResult, Machine, PlaceTy, Projectable, Scalar}; +use super::{ + ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy, Projectable, Scalar, +}; use crate::util; impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -303,6 +305,27 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let variant_dest = self.project_downcast(dest, variant_index)?; (variant_index, variant_dest, active_field_index) } + mir::AggregateKind::RawPtr(..) => { + // Pointers don't have "fields" in the normal sense, so the + // projection-based code below would either fail in projection + // or in type mismatches. Instead, build an `Immediate` from + // the parts and write that to the destination. + let [data, meta] = &operands.raw else { + bug!("{kind:?} should have 2 operands, had {operands:?}"); + }; + let data = self.eval_operand(data, None)?; + let data = self.read_pointer(&data)?; + let meta = self.eval_operand(meta, None)?; + let meta = if meta.layout.is_zst() { + MemPlaceMeta::None + } else { + MemPlaceMeta::Meta(self.read_scalar(&meta)?) + }; + let ptr_imm = Immediate::new_pointer_with_meta(data, meta, self); + let ptr = ImmTy::from_immediate(ptr_imm, dest.layout); + self.copy_op(&ptr, dest)?; + return Ok(()); + } _ => (FIRST_VARIANT, dest.clone(), None), }; if active_field_index.is_some() { diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index a499e4b980f..bf5592c828f 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -923,6 +923,47 @@ 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) { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index bd64621f077..fb4a76bf089 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -128,6 +128,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) - | sym::variant_count | sym::is_val_statically_known | sym::ptr_mask + | sym::aggregate_raw_ptr | sym::ub_checks | sym::fadd_algebraic | sym::fsub_algebraic @@ -574,6 +575,10 @@ pub fn check_intrinsic_type( (0, 0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize) } + // This type check is not particularly useful, but the `where` bounds + // on the definition in `core` do the heavy lifting for checking it. + sym::aggregate_raw_ptr => (3, 1, vec![param(1), param(2)], param(0)), + sym::ub_checks => (0, 1, Vec::new(), tcx.types.bool), sym::simd_eq diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index d340a08ee79..dd76862451c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -228,8 +228,8 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( // Check whether this segment takes generic arguments and the user has provided any. let (generic_args, infer_args) = ctx.args_for_def_id(def_id); - let args_iter = generic_args.iter().flat_map(|generic_args| generic_args.args.iter()); - let mut args_iter = args_iter.clone().peekable(); + let mut args_iter = + generic_args.iter().flat_map(|generic_args| generic_args.args.iter()).peekable(); // If we encounter a type or const when we expect a lifetime, we infer the lifetimes. // If we later encounter a lifetime, we know that the arguments were provided in the diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index a3cdcec9ec0..8291404ebf3 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -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, "") + } } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 97c3eb55638..db13bb9a3e8 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -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)] diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 506003ff7c0..abe99f3e95c 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -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, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 4f7b2f7cbe4..fc1ab0f12ac 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -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 { diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 8e8d78226c3..24832086b16 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -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 diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index ff786d44d6a..fd768cc96ae 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -36,6 +36,7 @@ impl<'tcx> MirPass<'tcx> for InstSimplify { ctx.simplify_bool_cmp(&statement.source_info, rvalue); ctx.simplify_ref_deref(&statement.source_info, rvalue); ctx.simplify_len(&statement.source_info, rvalue); + ctx.simplify_ptr_aggregate(&statement.source_info, rvalue); ctx.simplify_cast(rvalue); } _ => {} @@ -58,8 +59,17 @@ struct InstSimplifyContext<'tcx, 'a> { impl<'tcx> InstSimplifyContext<'tcx, '_> { fn should_simplify(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool { + self.should_simplify_custom(source_info, "Rvalue", rvalue) + } + + fn should_simplify_custom( + &self, + source_info: &SourceInfo, + label: &str, + value: impl std::fmt::Debug, + ) -> bool { self.tcx.consider_optimizing(|| { - format!("InstSimplify - Rvalue: {rvalue:?} SourceInfo: {source_info:?}") + format!("InstSimplify - {label}: {value:?} SourceInfo: {source_info:?}") }) } @@ -111,7 +121,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { if a.const_.ty().is_bool() { a.const_.try_to_bool() } else { None } } - /// Transform "&(*a)" ==> "a". + /// Transform `&(*a)` ==> `a`. fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Ref(_, _, place) = rvalue { if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() { @@ -131,7 +141,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { } } - /// Transform "Len([_; N])" ==> "N". + /// Transform `Len([_; N])` ==> `N`. fn simplify_len(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Len(ref place) = *rvalue { let place_ty = place.ty(self.local_decls, self.tcx).ty; @@ -147,6 +157,30 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { } } + /// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`. + fn simplify_ptr_aggregate(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue + { + let meta_ty = fields.raw[1].ty(self.local_decls, self.tcx); + if meta_ty.is_unit() { + // The mutable borrows we're holding prevent printing `rvalue` here + if !self.should_simplify_custom( + source_info, + "Aggregate::RawPtr", + (&pointee_ty, *mutability, &fields), + ) { + return; + } + + let mut fields = std::mem::take(fields); + let _meta = fields.pop().unwrap(); + let data = fields.pop().unwrap(); + let ptr_ty = Ty::new_ptr(self.tcx, *pointee_ty, *mutability); + *rvalue = Rvalue::Cast(CastKind::PtrToPtr, data, ptr_ty); + } + } + } + fn simplify_ub_check(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue { let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks()); diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 2744026a7c9..b8dbf8a759f 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -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, diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 7e8920604c1..da63fcf23d9 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -287,6 +287,34 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { terminator.kind = TerminatorKind::Unreachable; } } + sym::aggregate_raw_ptr => { + let Ok([data, meta]) = <[_; 2]>::try_from(std::mem::take(args)) else { + span_bug!( + terminator.source_info.span, + "Wrong number of arguments for aggregate_raw_ptr intrinsic", + ); + }; + let target = target.unwrap(); + let pointer_ty = generic_args.type_at(0); + let kind = if let ty::RawPtr(pointee_ty, mutability) = pointer_ty.kind() { + AggregateKind::RawPtr(*pointee_ty, *mutability) + } else { + span_bug!( + terminator.source_info.span, + "Return type of aggregate_raw_ptr intrinsic must be a raw pointer", + ); + }; + let fields = [data.node, meta.node]; + block.statements.push(Statement { + source_info: terminator.source_info, + kind: StatementKind::Assign(Box::new(( + *destination, + Rvalue::Aggregate(Box::new(kind), fields.into()), + ))), + }); + + terminator.kind = TerminatorKind::Goto { target }; + } _ => {} } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index c9f66612590..7c021621103 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -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)) + } } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 46bae1c1e98..f5eeb3d4ff1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -361,6 +361,7 @@ symbols! { adt_const_params, advanced_slice_patterns, adx_target_feature, + aggregate_raw_ptr, alias, align, align_offset, diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 1ad05633d62..6f666406c22 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -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)] |
