about summary refs log tree commit diff
path: root/compiler/rustc_public/src/alloc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_public/src/alloc.rs')
-rw-r--r--compiler/rustc_public/src/alloc.rs76
1 files changed, 76 insertions, 0 deletions
diff --git a/compiler/rustc_public/src/alloc.rs b/compiler/rustc_public/src/alloc.rs
new file mode 100644
index 00000000000..d2db6c08bbc
--- /dev/null
+++ b/compiler/rustc_public/src/alloc.rs
@@ -0,0 +1,76 @@
+//! Memory allocation implementation for StableMIR.
+//!
+//! This module is responsible for constructing stable components.
+//! All operations requiring rustc queries must be delegated
+//! to `rustc_public_bridge::alloc` to maintain stability guarantees.
+
+use rustc_abi::Align;
+use rustc_middle::mir::ConstValue;
+use rustc_middle::mir::interpret::AllocRange;
+use rustc_public_bridge::bridge::SmirError;
+use rustc_public_bridge::context::SmirCtxt;
+use rustc_public_bridge::{Tables, alloc};
+
+use super::Error;
+use super::compiler_interface::BridgeTys;
+use super::mir::Mutability;
+use super::ty::{Allocation, ProvenanceMap};
+use super::unstable::Stable;
+
+/// Creates new empty `Allocation` from given `Align`.
+fn new_empty_allocation(align: Align) -> Allocation {
+    Allocation {
+        bytes: Vec::new(),
+        provenance: ProvenanceMap { ptrs: Vec::new() },
+        align: align.bytes(),
+        mutability: Mutability::Not,
+    }
+}
+
+// We need this method instead of a Stable implementation
+// because we need to get `Ty` of the const we are trying to create, to do that
+// we need to have access to `ConstantKind` but we can't access that inside Stable impl.
+#[allow(rustc::usage_of_qualified_ty)]
+pub(crate) fn new_allocation<'tcx>(
+    ty: rustc_middle::ty::Ty<'tcx>,
+    const_value: ConstValue<'tcx>,
+    tables: &mut Tables<'tcx, BridgeTys>,
+    cx: &SmirCtxt<'tcx, BridgeTys>,
+) -> Allocation {
+    try_new_allocation(ty, const_value, tables, cx)
+        .unwrap_or_else(|_| panic!("Failed to convert: {const_value:?} to {ty:?}"))
+}
+
+#[allow(rustc::usage_of_qualified_ty)]
+pub(crate) fn try_new_allocation<'tcx>(
+    ty: rustc_middle::ty::Ty<'tcx>,
+    const_value: ConstValue<'tcx>,
+    tables: &mut Tables<'tcx, BridgeTys>,
+    cx: &SmirCtxt<'tcx, BridgeTys>,
+) -> Result<Allocation, Error> {
+    let layout = alloc::create_ty_and_layout(cx, ty).map_err(|e| Error::from_internal(e))?;
+    match const_value {
+        ConstValue::Scalar(scalar) => {
+            alloc::try_new_scalar(layout, scalar, cx).map(|alloc| alloc.stable(tables, cx))
+        }
+        ConstValue::ZeroSized => Ok(new_empty_allocation(layout.align.abi)),
+        ConstValue::Slice { data, meta } => {
+            alloc::try_new_slice(layout, data, meta, cx).map(|alloc| alloc.stable(tables, cx))
+        }
+        ConstValue::Indirect { alloc_id, offset } => {
+            let alloc = alloc::try_new_indirect(alloc_id, cx);
+            use rustc_public_bridge::context::SmirAllocRange;
+            Ok(allocation_filter(&alloc.0, cx.alloc_range(offset, layout.size), tables, cx))
+        }
+    }
+}
+
+/// Creates an `Allocation` only from information within the `AllocRange`.
+pub(super) fn allocation_filter<'tcx>(
+    alloc: &rustc_middle::mir::interpret::Allocation,
+    alloc_range: AllocRange,
+    tables: &mut Tables<'tcx, BridgeTys>,
+    cx: &SmirCtxt<'tcx, BridgeTys>,
+) -> Allocation {
+    alloc::allocation_filter(alloc, alloc_range, tables, cx)
+}