Skip to content

Commit 4eb8d94

Browse files
committed
Add a convenience macro to reduce code duplication
1 parent 0a84ff0 commit 4eb8d94

File tree

1 file changed

+86
-114
lines changed

1 file changed

+86
-114
lines changed

src/librustc_mir/interpret/snapshot.rs

Lines changed: 86 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,60 @@ use super::eval_context::{LocalValue, StackPopCleanup};
1414
use super::{Frame, Memory, Machine, Operand, MemPlace, Place, Value};
1515

1616
trait SnapshotContext<'a> {
17-
type To;
18-
type From;
19-
fn resolve(&'a self, id: &Self::From) -> Option<&'a Self::To>;
17+
fn resolve(&'a self, id: &AllocId) -> Option<&'a Allocation>;
2018
}
2119

2220
trait Snapshot<'a, Ctx: SnapshotContext<'a>> {
2321
type Item;
2422
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item;
2523
}
2624

25+
macro_rules! __impl_snapshot_field {
26+
($field:ident, $ctx:expr) => ($field.snapshot($ctx));
27+
($field:ident, $ctx:expr, $delegate:expr) => ($delegate);
28+
}
29+
30+
macro_rules! impl_snapshot_for {
31+
// FIXME(mark-i-m): Some of these should be `?` rather than `*`.
32+
(enum $enum_name:ident { $( $variant:ident $( ( $($field:ident $(-> $delegate:expr)*),* ) )* ),* $(,)* }) => {
33+
impl<'a, Ctx> self::Snapshot<'a, Ctx> for $enum_name
34+
where Ctx: self::SnapshotContext<'a>,
35+
{
36+
type Item = $enum_name<AllocIdSnapshot<'a>>;
37+
38+
#[inline]
39+
fn snapshot(&self, __ctx: &'a Ctx) -> Self::Item {
40+
match *self {
41+
$(
42+
$enum_name::$variant $( ( $(ref $field),* ) )* =>
43+
$enum_name::$variant $( ( $( __impl_snapshot_field!($field, __ctx $(, $delegate)*) ),* ), )*
44+
)*
45+
}
46+
}
47+
}
48+
};
49+
50+
// FIXME(mark-i-m): same here.
51+
(struct $struct_name:ident { $($field:ident $(-> $delegate:expr)*),* $(,)* }) => {
52+
impl<'a, Ctx> self::Snapshot<'a, Ctx> for $struct_name
53+
where Ctx: self::SnapshotContext<'a>,
54+
{
55+
type Item = $struct_name<AllocIdSnapshot<'a>>;
56+
57+
#[inline]
58+
fn snapshot(&self, __ctx: &'a Ctx) -> Self::Item {
59+
let $struct_name {
60+
$(ref $field),*
61+
} = *self;
62+
63+
$struct_name {
64+
$( $field: __impl_snapshot_field!($field, __ctx $(, $delegate)*) ),*
65+
}
66+
}
67+
}
68+
};
69+
}
70+
2771
impl<'a, Ctx, T> Snapshot<'a, Ctx> for Option<T>
2872
where Ctx: SnapshotContext<'a>,
2973
T: Snapshot<'a, Ctx>
@@ -42,7 +86,7 @@ impl<'a, Ctx, T> Snapshot<'a, Ctx> for Option<T>
4286
struct AllocIdSnapshot<'a>(Option<AllocationSnapshot<'a>>);
4387

4488
impl<'a, Ctx> Snapshot<'a, Ctx> for AllocId
45-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
89+
where Ctx: SnapshotContext<'a>,
4690
{
4791
type Item = AllocIdSnapshot<'a>;
4892

@@ -51,80 +95,42 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for AllocId
5195
}
5296
}
5397

54-
type PointerSnapshot<'a> = Pointer<AllocIdSnapshot<'a>>;
55-
56-
impl<'a, Ctx> Snapshot<'a, Ctx> for Pointer
57-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
58-
{
59-
type Item = PointerSnapshot<'a>;
60-
61-
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
62-
let Pointer{ alloc_id, offset } = self;
63-
64-
Pointer {
65-
alloc_id: alloc_id.snapshot(ctx),
66-
offset: *offset,
67-
}
68-
}
69-
}
70-
71-
type ScalarSnapshot<'a> = Scalar<AllocIdSnapshot<'a>>;
98+
impl_snapshot_for!(struct Pointer {
99+
alloc_id,
100+
offset -> *offset,
101+
});
72102

73103
impl<'a, Ctx> Snapshot<'a, Ctx> for Scalar
74-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
104+
where Ctx: SnapshotContext<'a>,
75105
{
76-
type Item = ScalarSnapshot<'a>;
106+
type Item = Scalar<AllocIdSnapshot<'a>>;
77107

78108
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
79109
match self {
80110
Scalar::Ptr(p) => Scalar::Ptr(p.snapshot(ctx)),
81-
Scalar::Bits{ size, bits } => Scalar::Bits{
111+
Scalar::Bits{ size, bits } => Scalar::Bits {
82112
size: *size,
83113
bits: *bits,
84114
},
85115
}
86116
}
87117
}
88118

89-
type ScalarMaybeUndefSnapshot<'a> = ScalarMaybeUndef<AllocIdSnapshot<'a>>;
90-
91-
impl<'a, Ctx> Snapshot<'a, Ctx> for ScalarMaybeUndef
92-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
93-
{
94-
type Item = ScalarMaybeUndefSnapshot<'a>;
95-
96-
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
97-
match self {
98-
ScalarMaybeUndef::Scalar(s) => ScalarMaybeUndef::Scalar(s.snapshot(ctx)),
99-
ScalarMaybeUndef::Undef => ScalarMaybeUndef::Undef,
100-
}
101-
}
102-
}
103-
104-
type MemPlaceSnapshot<'a> = MemPlace<AllocIdSnapshot<'a>>;
105-
106-
impl<'a, Ctx> Snapshot<'a, Ctx> for MemPlace
107-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
108-
{
109-
type Item = MemPlaceSnapshot<'a>;
119+
impl_snapshot_for!(enum ScalarMaybeUndef {
120+
Scalar(s),
121+
Undef,
122+
});
110123

111-
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
112-
let MemPlace{ ptr, extra, align } = self;
113-
114-
MemPlaceSnapshot{
115-
ptr: ptr.snapshot(ctx),
116-
extra: extra.snapshot(ctx),
117-
align: *align,
118-
}
119-
}
120-
}
121-
122-
type PlaceSnapshot<'a> = Place<AllocIdSnapshot<'a>>;
124+
impl_snapshot_for!(struct MemPlace {
125+
ptr,
126+
extra,
127+
align -> *align,
128+
});
123129

124130
impl<'a, Ctx> Snapshot<'a, Ctx> for Place
125-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
131+
where Ctx: SnapshotContext<'a>,
126132
{
127-
type Item = PlaceSnapshot<'a>;
133+
type Item = Place<AllocIdSnapshot<'a>>;
128134

129135
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
130136
match self {
@@ -138,57 +144,25 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for Place
138144
}
139145
}
140146

141-
type ValueSnapshot<'a> = Value<AllocIdSnapshot<'a>>;
142-
143-
impl<'a, Ctx> Snapshot<'a, Ctx> for Value
144-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
145-
{
146-
type Item = ValueSnapshot<'a>;
147-
148-
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
149-
match self {
150-
Value::Scalar(s) => Value::Scalar(s.snapshot(ctx)),
151-
Value::ScalarPair(a, b) => Value::ScalarPair(a.snapshot(ctx), b.snapshot(ctx)),
152-
}
153-
}
154-
}
147+
impl_snapshot_for!(enum Value {
148+
Scalar(s),
149+
ScalarPair(s, t),
150+
});
155151

156-
type OperandSnapshot<'a> = Operand<AllocIdSnapshot<'a>>;
152+
impl_snapshot_for!(enum Operand {
153+
Immediate(v),
154+
Indirect(m),
155+
});
157156

158-
impl<'a, Ctx> Snapshot<'a, Ctx> for Operand
159-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
160-
{
161-
type Item = OperandSnapshot<'a>;
162-
163-
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
164-
match self {
165-
Operand::Immediate(v) => Operand::Immediate(v.snapshot(ctx)),
166-
Operand::Indirect(m) => Operand::Indirect(m.snapshot(ctx)),
167-
}
168-
}
169-
}
170-
171-
type LocalValueSnapshot<'a> = LocalValue<AllocIdSnapshot<'a>>;
172-
173-
impl<'a, Ctx> Snapshot<'a, Ctx> for LocalValue
174-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
175-
{
176-
type Item = LocalValueSnapshot<'a>;
177-
178-
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
179-
match self {
180-
LocalValue::Live(v) => LocalValue::Live(v.snapshot(ctx)),
181-
LocalValue::Dead => LocalValue::Dead,
182-
}
183-
}
184-
}
185-
186-
type RelocationsSnapshot<'a> = Relocations<AllocIdSnapshot<'a>>;
157+
impl_snapshot_for!(enum LocalValue {
158+
Live(v),
159+
Dead,
160+
});
187161

188162
impl<'a, Ctx> Snapshot<'a, Ctx> for Relocations
189-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
163+
where Ctx: SnapshotContext<'a>,
190164
{
191-
type Item = RelocationsSnapshot<'a>;
165+
type Item = Relocations<AllocIdSnapshot<'a>>;
192166

193167
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
194168
Relocations::from_presorted(self.iter().map(|(size, id)| (*size, id.snapshot(ctx))).collect())
@@ -198,14 +172,14 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for Relocations
198172
#[derive(Eq, PartialEq)]
199173
struct AllocationSnapshot<'a> {
200174
bytes: &'a [u8],
201-
relocations: RelocationsSnapshot<'a>,
175+
relocations: Relocations<AllocIdSnapshot<'a>>,
202176
undef_mask: &'a UndefMask,
203177
align: &'a Align,
204178
mutability: &'a Mutability,
205179
}
206180

207181
impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
208-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
182+
where Ctx: SnapshotContext<'a>,
209183
{
210184
type Item = AllocationSnapshot<'a>;
211185

@@ -227,14 +201,14 @@ struct FrameSnapshot<'a, 'tcx: 'a> {
227201
instance: &'a ty::Instance<'tcx>,
228202
span: &'a Span,
229203
return_to_block: &'a StackPopCleanup,
230-
return_place: PlaceSnapshot<'a>,
231-
locals: IndexVec<mir::Local, LocalValueSnapshot<'a>>,
204+
return_place: Place<AllocIdSnapshot<'a>>,
205+
locals: IndexVec<mir::Local, LocalValue<AllocIdSnapshot<'a>>>,
232206
block: &'a mir::BasicBlock,
233207
stmt: usize,
234208
}
235209

236210
impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx>
237-
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
211+
where Ctx: SnapshotContext<'a>,
238212
{
239213
type Item = FrameSnapshot<'a, 'tcx>;
240214

@@ -279,9 +253,7 @@ impl<'a, 'mir, 'tcx, M> Memory<'a, 'mir, 'tcx, M>
279253
impl<'a, 'b, 'mir, 'tcx, M> SnapshotContext<'b> for Memory<'a, 'mir, 'tcx, M>
280254
where M: Machine<'mir, 'tcx>,
281255
{
282-
type To = Allocation;
283-
type From = AllocId;
284-
fn resolve(&'b self, id: &Self::From) -> Option<&'b Self::To> {
256+
fn resolve(&'b self, id: &AllocId) -> Option<&'b Allocation> {
285257
self.get(*id).ok()
286258
}
287259
}

0 commit comments

Comments
 (0)