@@ -131,6 +131,10 @@ pub struct ScalarInt {
131
131
// can't take references to fields of packed structs.
132
132
impl < CTX > crate :: ty:: HashStable < CTX > for ScalarInt {
133
133
fn hash_stable ( & self , hcx : & mut CTX , hasher : & mut crate :: ty:: StableHasher ) {
134
+ // Using a block `{self.data}` here to force a copy instead of using `self.data`
135
+ // directly, because `hash_stable` takes `&self` and would thus borrow `self.data`.
136
+ // Since `Self` is a packed struct, that would create a possibly unaligned reference,
137
+ // which is UB on a lot of platforms.
134
138
{ self . data } . hash_stable ( hcx, hasher) ;
135
139
self . size . hash_stable ( hcx, hasher) ;
136
140
}
@@ -167,6 +171,11 @@ impl ScalarInt {
167
171
/// construct `Scalar`s).
168
172
#[ inline( always) ]
169
173
fn check_data ( self ) {
174
+ // Using a block `{self.data}` here to force a copy instead of using `self.data`
175
+ // directly, because `assert_eq` takes references to its arguments and formatting
176
+ // arguments and would thus borrow `self.data`. Since `Self`
177
+ // is a packed struct, that would create a possibly unaligned reference, which
178
+ // is UB on a lot of platforms.
170
179
debug_assert_eq ! (
171
180
truncate( self . data, self . size( ) ) ,
172
181
{ self . data } ,
@@ -336,6 +345,11 @@ impl fmt::LowerHex for ScalarInt {
336
345
self . check_data ( ) ;
337
346
// Format as hex number wide enough to fit any value of the given `size`.
338
347
// So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
348
+ // Using a block `{self.data}` here to force a copy instead of using `self.data`
349
+ // directly, because `write!` takes references to its formatting arguments and
350
+ // would thus borrow `self.data`. Since `Self`
351
+ // is a packed struct, that would create a possibly unaligned reference, which
352
+ // is UB on a lot of platforms.
339
353
write ! ( f, "{:01$x}" , { self . data } , self . size as usize * 2 )
340
354
}
341
355
}
0 commit comments