1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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)
}
|