Skip to content

Commit efbee50

Browse files
committed
avoid manual Debug impls by adding extra Provenance bounds to types
I wish the derive macro would support adding extra where clauses...
1 parent a5299fb commit efbee50

File tree

4 files changed

+51
-152
lines changed

4 files changed

+51
-152
lines changed

Diff for: compiler/rustc_middle/src/mir/interpret/pointer.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ impl<T: HasDataLayout> PointerArithmetic for T {}
8686
/// This trait abstracts over the kind of provenance that is associated with a `Pointer`. It is
8787
/// mostly opaque; the `Machine` trait extends it with some more operations that also have access to
8888
/// some global state.
89-
pub trait Provenance: Copy {
89+
/// We don't actually care about this `Debug` bound (we use `Provenance::fmt` to format the entire
90+
/// pointer), but `derive` adds some unecessary bounds.
91+
pub trait Provenance: Copy + fmt::Debug {
9092
/// Says whether the `offset` field of `Pointer`s with this provenance is the actual physical address.
9193
/// If `true, ptr-to-int casts work by simply discarding the provenance.
9294
/// If `false`, ptr-to-int casts are not supported. The offset *must* be relative in that case.
@@ -142,14 +144,14 @@ static_assert_size!(Pointer, 16);
142144
// all the Miri types.
143145
impl<Tag: Provenance> fmt::Debug for Pointer<Tag> {
144146
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145-
Tag::fmt(self, f)
147+
Provenance::fmt(self, f)
146148
}
147149
}
148150

149151
impl<Tag: Provenance> fmt::Debug for Pointer<Option<Tag>> {
150152
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151153
match self.provenance {
152-
Some(tag) => Tag::fmt(&Pointer::new(tag, self.offset), f),
154+
Some(tag) => Provenance::fmt(&Pointer::new(tag, self.offset), f),
153155
None => write!(f, "0x{:x}", self.offset.bytes()),
154156
}
155157
}

Diff for: compiler/rustc_mir/src/interpret/eval_context.rs

+8-20
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl Drop for SpanGuard {
8080
}
8181

8282
/// A stack frame.
83-
pub struct Frame<'mir, 'tcx, Tag = AllocId, Extra = ()> {
83+
pub struct Frame<'mir, 'tcx, Tag: Provenance = AllocId, Extra = ()> {
8484
////////////////////////////////////////////////////////////////////////////////
8585
// Function and callsite information
8686
////////////////////////////////////////////////////////////////////////////////
@@ -161,16 +161,16 @@ pub enum StackPopCleanup {
161161

162162
/// State of a local variable including a memoized layout
163163
#[derive(Clone, PartialEq, Eq, HashStable)]
164-
pub struct LocalState<'tcx, Tag = AllocId> {
164+
pub struct LocalState<'tcx, Tag: Provenance = AllocId> {
165165
pub value: LocalValue<Tag>,
166166
/// Don't modify if `Some`, this is only used to prevent computing the layout twice
167167
#[stable_hasher(ignore)]
168168
pub layout: Cell<Option<TyAndLayout<'tcx>>>,
169169
}
170170

171171
/// Current value of a local variable
172-
#[derive(Copy, Clone, PartialEq, Eq, HashStable)]
173-
pub enum LocalValue<Tag = AllocId> {
172+
#[derive(Copy, Clone, PartialEq, Eq, HashStable, Debug)] // Miri debug-prints these
173+
pub enum LocalValue<Tag: Provenance = AllocId> {
174174
/// This local is not currently alive, and cannot be used at all.
175175
Dead,
176176
/// This local is alive but not yet initialized. It can be written to
@@ -186,19 +186,7 @@ pub enum LocalValue<Tag = AllocId> {
186186
Live(Operand<Tag>),
187187
}
188188

189-
impl<Tag: Provenance> std::fmt::Debug for LocalValue<Tag> {
190-
// Miri debug-prints these
191-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
192-
use LocalValue::*;
193-
match self {
194-
Dead => f.debug_tuple("Dead").finish(),
195-
Uninitialized => f.debug_tuple("Uninitialized").finish(),
196-
Live(o) => f.debug_tuple("Live").field(o).finish(),
197-
}
198-
}
199-
}
200-
201-
impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
189+
impl<'tcx, Tag: Provenance + 'static> LocalState<'tcx, Tag> {
202190
/// Read the local's value or error if the local is not yet live or not live anymore.
203191
///
204192
/// Note: This may only be invoked from the `Machine::access_local` hook and not from
@@ -232,7 +220,7 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
232220
}
233221
}
234222

235-
impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> {
223+
impl<'mir, 'tcx, Tag: Provenance> Frame<'mir, 'tcx, Tag> {
236224
pub fn with_extra<Extra>(self, extra: Extra) -> Frame<'mir, 'tcx, Tag, Extra> {
237225
Frame {
238226
body: self.body,
@@ -247,7 +235,7 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> {
247235
}
248236
}
249237

250-
impl<'mir, 'tcx, Tag, Extra> Frame<'mir, 'tcx, Tag, Extra> {
238+
impl<'mir, 'tcx, Tag: Provenance, Extra> Frame<'mir, 'tcx, Tag, Extra> {
251239
/// Get the current location within the Frame.
252240
///
253241
/// If this is `Err`, we are not currently executing any particular statement in
@@ -1024,7 +1012,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug
10241012
}
10251013
}
10261014

1027-
impl<'ctx, 'mir, 'tcx, Tag, Extra> HashStable<StableHashingContext<'ctx>>
1015+
impl<'ctx, 'mir, 'tcx, Tag: Provenance, Extra> HashStable<StableHashingContext<'ctx>>
10281016
for Frame<'mir, 'tcx, Tag, Extra>
10291017
where
10301018
Extra: HashStable<StableHashingContext<'ctx>>,

Diff for: compiler/rustc_mir/src/interpret/operand.rs

+19-56
Original file line numberDiff line numberDiff line change
@@ -27,40 +27,30 @@ use super::{
2727
/// operations and wide pointers. This idea was taken from rustc's codegen.
2828
/// In particular, thanks to `ScalarPair`, arithmetic operations and casts can be entirely
2929
/// defined on `Immediate`, and do not have to work with a `Place`.
30-
#[derive(Copy, Clone, PartialEq, Eq, HashStable, Hash)]
31-
pub enum Immediate<Tag = AllocId> {
30+
#[derive(Copy, Clone, PartialEq, Eq, HashStable, Hash, Debug)]
31+
pub enum Immediate<Tag: Provenance = AllocId> {
3232
Scalar(ScalarMaybeUninit<Tag>),
3333
ScalarPair(ScalarMaybeUninit<Tag>, ScalarMaybeUninit<Tag>),
3434
}
3535

3636
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
3737
rustc_data_structures::static_assert_size!(Immediate, 56);
3838

39-
impl<Tag: Provenance> std::fmt::Debug for Immediate<Tag> {
40-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41-
use Immediate::*;
42-
match self {
43-
Scalar(s) => f.debug_tuple("Scalar").field(s).finish(),
44-
ScalarPair(s1, s2) => f.debug_tuple("ScalarPair").field(s1).field(s2).finish(),
45-
}
46-
}
47-
}
48-
49-
impl<Tag> From<ScalarMaybeUninit<Tag>> for Immediate<Tag> {
39+
impl<Tag: Provenance> From<ScalarMaybeUninit<Tag>> for Immediate<Tag> {
5040
#[inline(always)]
5141
fn from(val: ScalarMaybeUninit<Tag>) -> Self {
5242
Immediate::Scalar(val)
5343
}
5444
}
5545

56-
impl<Tag> From<Scalar<Tag>> for Immediate<Tag> {
46+
impl<Tag: Provenance> From<Scalar<Tag>> for Immediate<Tag> {
5747
#[inline(always)]
5848
fn from(val: Scalar<Tag>) -> Self {
5949
Immediate::Scalar(val.into())
6050
}
6151
}
6252

63-
impl<'tcx, Tag> Immediate<Tag> {
53+
impl<'tcx, Tag: Provenance> Immediate<Tag> {
6454
pub fn from_pointer(p: Pointer<Tag>, cx: &impl HasDataLayout) -> Self {
6555
Immediate::Scalar(ScalarMaybeUninit::from_pointer(p, cx))
6656
}
@@ -93,22 +83,15 @@ impl<'tcx, Tag> Immediate<Tag> {
9383

9484
// ScalarPair needs a type to interpret, so we often have an immediate and a type together
9585
// as input for binary and cast operations.
96-
#[derive(Copy, Clone)]
97-
pub struct ImmTy<'tcx, Tag = AllocId> {
86+
#[derive(Copy, Clone, Debug)]
87+
pub struct ImmTy<'tcx, Tag: Provenance = AllocId> {
9888
imm: Immediate<Tag>,
9989
pub layout: TyAndLayout<'tcx>,
10090
}
10191

10292
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
10393
rustc_data_structures::static_assert_size!(ImmTy<'_>, 72);
10494

105-
impl<'tcx, Tag: Provenance> std::fmt::Debug for ImmTy<'tcx, Tag> {
106-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107-
let ImmTy { imm, layout } = self;
108-
f.debug_struct("ImmTy").field("imm", imm).field("layout", layout).finish()
109-
}
110-
}
111-
11295
impl<Tag: Provenance> std::fmt::Display for ImmTy<'tcx, Tag> {
11396
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11497
/// Helper function for printing a scalar to a FmtPrinter
@@ -156,7 +139,7 @@ impl<Tag: Provenance> std::fmt::Display for ImmTy<'tcx, Tag> {
156139
}
157140
}
158141

159-
impl<'tcx, Tag> std::ops::Deref for ImmTy<'tcx, Tag> {
142+
impl<'tcx, Tag: Provenance> std::ops::Deref for ImmTy<'tcx, Tag> {
160143
type Target = Immediate<Tag>;
161144
#[inline(always)]
162145
fn deref(&self) -> &Immediate<Tag> {
@@ -167,68 +150,51 @@ impl<'tcx, Tag> std::ops::Deref for ImmTy<'tcx, Tag> {
167150
/// An `Operand` is the result of computing a `mir::Operand`. It can be immediate,
168151
/// or still in memory. The latter is an optimization, to delay reading that chunk of
169152
/// memory and to avoid having to store arbitrary-sized data here.
170-
#[derive(Copy, Clone, PartialEq, Eq, HashStable, Hash)]
171-
pub enum Operand<Tag = AllocId> {
153+
#[derive(Copy, Clone, PartialEq, Eq, HashStable, Hash, Debug)]
154+
pub enum Operand<Tag: Provenance = AllocId> {
172155
Immediate(Immediate<Tag>),
173156
Indirect(MemPlace<Tag>),
174157
}
175158

176-
impl<Tag: Provenance> std::fmt::Debug for Operand<Tag> {
177-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178-
use Operand::*;
179-
match self {
180-
Immediate(i) => f.debug_tuple("Immediate").field(i).finish(),
181-
Indirect(p) => f.debug_tuple("Indirect").field(p).finish(),
182-
}
183-
}
184-
}
185-
186-
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
187-
pub struct OpTy<'tcx, Tag = AllocId> {
159+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
160+
pub struct OpTy<'tcx, Tag: Provenance = AllocId> {
188161
op: Operand<Tag>, // Keep this private; it helps enforce invariants.
189162
pub layout: TyAndLayout<'tcx>,
190163
}
191164

192165
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
193-
rustc_data_structures::static_assert_size!(OpTy<'_, ()>, 80);
194-
195-
impl<'tcx, Tag: Provenance> std::fmt::Debug for OpTy<'tcx, Tag> {
196-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197-
let OpTy { op, layout } = self;
198-
f.debug_struct("OpTy").field("op", op).field("layout", layout).finish()
199-
}
200-
}
166+
rustc_data_structures::static_assert_size!(OpTy<'_>, 80);
201167

202-
impl<'tcx, Tag> std::ops::Deref for OpTy<'tcx, Tag> {
168+
impl<'tcx, Tag: Provenance> std::ops::Deref for OpTy<'tcx, Tag> {
203169
type Target = Operand<Tag>;
204170
#[inline(always)]
205171
fn deref(&self) -> &Operand<Tag> {
206172
&self.op
207173
}
208174
}
209175

210-
impl<'tcx, Tag: Copy> From<MPlaceTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
176+
impl<'tcx, Tag: Provenance> From<MPlaceTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
211177
#[inline(always)]
212178
fn from(mplace: MPlaceTy<'tcx, Tag>) -> Self {
213179
OpTy { op: Operand::Indirect(*mplace), layout: mplace.layout }
214180
}
215181
}
216182

217-
impl<'tcx, Tag: Copy> From<&'_ MPlaceTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
183+
impl<'tcx, Tag: Provenance> From<&'_ MPlaceTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
218184
#[inline(always)]
219185
fn from(mplace: &MPlaceTy<'tcx, Tag>) -> Self {
220186
OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout }
221187
}
222188
}
223189

224-
impl<'tcx, Tag> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
190+
impl<'tcx, Tag: Provenance> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
225191
#[inline(always)]
226192
fn from(val: ImmTy<'tcx, Tag>) -> Self {
227193
OpTy { op: Operand::Immediate(val.imm), layout: val.layout }
228194
}
229195
}
230196

231-
impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
197+
impl<'tcx, Tag: Provenance> ImmTy<'tcx, Tag> {
232198
#[inline]
233199
pub fn from_scalar(val: Scalar<Tag>, layout: TyAndLayout<'tcx>) -> Self {
234200
ImmTy { imm: val.into(), layout }
@@ -259,10 +225,7 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
259225
}
260226

261227
#[inline]
262-
pub fn to_const_int(self) -> ConstInt
263-
where
264-
Tag: Provenance,
265-
{
228+
pub fn to_const_int(self) -> ConstInt {
266229
assert!(self.layout.ty.is_integral());
267230
let int = self.to_scalar().expect("to_const_int doesn't work on scalar pairs").assert_int();
268231
ConstInt::new(int, self.layout.ty.is_signed(), self.layout.ty.is_ptr_sized_integral())

0 commit comments

Comments
 (0)