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/rustc_const_eval | |
| 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/rustc_const_eval')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/step.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/validate.rs | 41 |
2 files changed, 65 insertions, 1 deletions
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) { |
