about summary refs log tree commit diff
path: root/compiler/rustc_const_eval
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-21 21:08:03 +0000
committerbors <bors@rust-lang.org>2024-04-21 21:08:03 +0000
commitfb898629a26e4acec59c928ce3ec00a62675d1cc (patch)
treeba73dfeeabaa003efb79a37a8cf7ae0de48e6cb5 /compiler/rustc_const_eval
parent1b3fba066c21e7c3471fca710783fc1e6546a1ca (diff)
parent3315bf961d4d7dfafe3f8b01f892317e4f746861 (diff)
downloadrust-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.rs25
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs41
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) {