@@ -182,22 +182,15 @@ macro_rules! transmute_ref {
182
182
// this macro expression is `&U` where `U: 'u + Sized + FromBytes +
183
183
// Immutable`, and that `'t` outlives `'u`.
184
184
185
- struct AssertSrcIsSized <' a, T : :: core:: marker:: Sized >( & ' a T ) ;
186
185
struct AssertSrcIsIntoBytes <' a, T : ?:: core:: marker:: Sized + $crate:: IntoBytes >( & ' a T ) ;
187
186
struct AssertSrcIsImmutable <' a, T : ?:: core:: marker:: Sized + $crate:: Immutable >( & ' a T ) ;
188
- struct AssertDstIsSized <' a, T : :: core:: marker:: Sized >( & ' a T ) ;
189
187
struct AssertDstIsFromBytes <' a, U : ?:: core:: marker:: Sized + $crate:: FromBytes >( & ' a U ) ;
190
188
struct AssertDstIsImmutable <' a, T : ?:: core:: marker:: Sized + $crate:: Immutable >( & ' a T ) ;
191
189
192
- let _ = AssertSrcIsSized ( e) ;
193
190
let _ = AssertSrcIsIntoBytes ( e) ;
194
191
let _ = AssertSrcIsImmutable ( e) ;
195
192
196
193
if true {
197
- #[ allow( unused, unreachable_code) ]
198
- let u = AssertDstIsSized ( loop { } ) ;
199
- u. 0
200
- } else if true {
201
194
#[ allow( unused, unreachable_code) ]
202
195
let u = AssertDstIsFromBytes ( loop { } ) ;
203
196
u. 0
@@ -206,36 +199,13 @@ macro_rules! transmute_ref {
206
199
let u = AssertDstIsImmutable ( loop { } ) ;
207
200
u. 0
208
201
}
209
- } else if false {
210
- // This branch, though never taken, ensures that `size_of::<T>() ==
211
- // size_of::<U>()` and that that `align_of::<T>() >=
212
- // align_of::<U>()`.
213
-
214
- // `t` is inferred to have type `T` because it's assigned to `e` (of
215
- // type `&T`) as `&t`.
216
- let mut t = loop { } ;
217
- e = & t;
218
-
219
- // `u` is inferred to have type `U` because it's used as `&u` as the
220
- // value returned from this branch.
221
- let u;
222
-
223
- $crate:: assert_size_eq!( t, u) ;
224
- $crate:: assert_align_gt_eq!( t, u) ;
225
-
226
- & u
227
202
} else {
228
- // SAFETY: For source type `Src` and destination type `Dst`:
229
- // - We know that `Src: IntoBytes + Immutable` and `Dst: FromBytes +
230
- // Immutable` thanks to the uses of `AssertSrcIsIntoBytes`,
231
- // `AssertSrcIsImmutable`, `AssertDstIsFromBytes`, and
232
- // `AssertDstIsImmutable` above.
233
- // - We know that `size_of::<Src>() == size_of::<Dst>()` thanks to
234
- // the use of `assert_size_eq!` above.
235
- // - We know that `align_of::<Src>() >= align_of::<Dst>()` thanks to
236
- // the use of `assert_align_gt_eq!` above.
237
- let u = unsafe { $crate:: util:: macro_util:: transmute_ref( e) } ;
238
- $crate:: util:: macro_util:: must_use( u)
203
+ use $crate:: util:: macro_util:: TransmuteRefDst ;
204
+ let t = $crate:: util:: macro_util:: Wrap ( e) ;
205
+ // SAFETY: todo
206
+ unsafe {
207
+ t. transmute_ref( )
208
+ }
239
209
}
240
210
} }
241
211
}
@@ -334,26 +304,18 @@ macro_rules! transmute_mut {
334
304
// writing, mutable references are banned), the error message
335
305
// appears to originate in the user's code rather than in the
336
306
// internals of this macro.
337
- struct AssertSrcIsSized <' a, T : :: core:: marker:: Sized >( & ' a T ) ;
338
307
struct AssertSrcIsFromBytes <' a, T : ?:: core:: marker:: Sized + $crate:: FromBytes >( & ' a T ) ;
339
308
struct AssertSrcIsIntoBytes <' a, T : ?:: core:: marker:: Sized + $crate:: IntoBytes >( & ' a T ) ;
340
- struct AssertDstIsSized <' a, T : :: core:: marker:: Sized >( & ' a T ) ;
341
309
struct AssertDstIsFromBytes <' a, T : ?:: core:: marker:: Sized + $crate:: FromBytes >( & ' a T ) ;
342
310
struct AssertDstIsIntoBytes <' a, T : ?:: core:: marker:: Sized + $crate:: IntoBytes >( & ' a T ) ;
343
311
344
312
if true {
345
- let _ = AssertSrcIsSized ( & * e) ;
346
- } else if true {
347
313
let _ = AssertSrcIsFromBytes ( & * e) ;
348
314
} else {
349
315
let _ = AssertSrcIsIntoBytes ( & * e) ;
350
316
}
351
317
352
318
if true {
353
- #[ allow( unused, unreachable_code) ]
354
- let u = AssertDstIsSized ( loop { } ) ;
355
- & mut * u. 0
356
- } else if true {
357
319
#[ allow( unused, unreachable_code) ]
358
320
let u = AssertDstIsFromBytes ( loop { } ) ;
359
321
& mut * u. 0
@@ -362,32 +324,13 @@ macro_rules! transmute_mut {
362
324
let u = AssertDstIsIntoBytes ( loop { } ) ;
363
325
& mut * u. 0
364
326
}
365
- } else if false {
366
- // This branch, though never taken, ensures that `size_of::<T>() ==
367
- // size_of::<U>()` and that that `align_of::<T>() >=
368
- // align_of::<U>()`.
369
-
370
- // `t` is inferred to have type `T` because it's assigned to `e` (of
371
- // type `&mut T`) as `&mut t`.
372
- let mut t = loop { } ;
373
- e = & mut t;
374
-
375
- // `u` is inferred to have type `U` because it's used as `&mut u` as
376
- // the value returned from this branch.
377
- let u;
378
-
379
- $crate:: assert_size_eq!( t, u) ;
380
- $crate:: assert_align_gt_eq!( t, u) ;
381
-
382
- & mut u
383
327
} else {
384
- // SAFETY: For source type `Src` and destination type `Dst`:
385
- // - We know that `size_of::<Src>() == size_of::<Dst>()` thanks to
386
- // the use of `assert_size_eq!` above.
387
- // - We know that `align_of::<Src>() >= align_of::<Dst>()` thanks to
388
- // the use of `assert_align_gt_eq!` above.
389
- let u = unsafe { $crate:: util:: macro_util:: transmute_mut( e) } ;
390
- $crate:: util:: macro_util:: must_use( u)
328
+ use $crate:: util:: macro_util:: TransmuteMutDst ;
329
+ let t = $crate:: util:: macro_util:: Wrap ( e) ;
330
+ // SAFETY: todo
331
+ unsafe {
332
+ t. transmute_mut( )
333
+ }
391
334
}
392
335
} }
393
336
}
@@ -1038,40 +981,71 @@ mod tests {
1038
981
assert_eq ! ( x. into_inner( ) , 1 ) ;
1039
982
}
1040
983
1041
- #[ test]
1042
- fn test_transmute_ref ( ) {
1043
- // Test that memory is transmuted as expected.
1044
- let array_of_u8s = [ 0u8 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ;
1045
- let array_of_arrays = [ [ 0 , 1 ] , [ 2 , 3 ] , [ 4 , 5 ] , [ 6 , 7 ] ] ;
1046
- let x: & [ [ u8 ; 2 ] ; 4 ] = transmute_ref ! ( & array_of_u8s) ;
1047
- assert_eq ! ( * x, array_of_arrays) ;
1048
- let x: & [ u8 ; 8 ] = transmute_ref ! ( & array_of_arrays) ;
1049
- assert_eq ! ( * x, array_of_u8s) ;
1050
-
1051
- // Test that `transmute_ref!` is legal in a const context.
1052
- const ARRAY_OF_U8S : [ u8 ; 8 ] = [ 0u8 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ;
1053
- const ARRAY_OF_ARRAYS : [ [ u8 ; 2 ] ; 4 ] = [ [ 0 , 1 ] , [ 2 , 3 ] , [ 4 , 5 ] , [ 6 , 7 ] ] ;
1054
- #[ allow( clippy:: redundant_static_lifetimes) ]
1055
- const X : & ' static [ [ u8 ; 2 ] ; 4 ] = transmute_ref ! ( & ARRAY_OF_U8S ) ;
1056
- assert_eq ! ( * X , ARRAY_OF_ARRAYS ) ;
1057
-
1058
- // Test that it's legal to transmute a reference while shrinking the
1059
- // lifetime (note that `X` has the lifetime `'static`).
1060
- let x: & [ u8 ; 8 ] = transmute_ref ! ( X ) ;
1061
- assert_eq ! ( * x, ARRAY_OF_U8S ) ;
1062
-
1063
- // Test that `transmute_ref!` supports decreasing alignment.
1064
- let u = AU64 ( 0 ) ;
1065
- let array = [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ;
1066
- let x: & [ u8 ; 8 ] = transmute_ref ! ( & u) ;
1067
- assert_eq ! ( * x, array) ;
1068
-
1069
- // Test that a mutable reference can be turned into an immutable one.
1070
- let mut x = 0u8 ;
1071
- #[ allow( clippy:: useless_transmute) ]
1072
- let y: & u8 = transmute_ref ! ( & mut x) ;
1073
- assert_eq ! ( * y, 0 ) ;
1074
- }
984
+ // #[test]
985
+ // fn test_transmute_ref() {
986
+ // // Test that memory is transmuted as expected.
987
+ // let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
988
+ // let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
989
+ // let x: &[[u8; 2]; 4] = transmute_ref!(&array_of_u8s);
990
+ // assert_eq!(*x, array_of_arrays);
991
+ // let x: &[u8; 8] = transmute_ref!(&array_of_arrays);
992
+ // assert_eq!(*x, array_of_u8s);
993
+
994
+ // // Test that `transmute_ref!` is legal in a const context.
995
+ // const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];
996
+ // const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];
997
+ // #[allow(clippy::redundant_static_lifetimes)]
998
+ // const X: &'static [[u8; 2]; 4] = transmute_ref!(&ARRAY_OF_U8S);
999
+ // assert_eq!(*X, ARRAY_OF_ARRAYS);
1000
+
1001
+ // // Test that `transmute_ref!` works on slice DSTs in and that memory is
1002
+ // // transmuted as expected.
1003
+ // #[derive(KnownLayout, Immutable, FromBytes, IntoBytes, PartialEq, Debug)]
1004
+ // #[repr(C)]
1005
+ // struct SliceDst<T> {
1006
+ // a: u8,
1007
+ // b: [T],
1008
+ // }
1009
+
1010
+ // use crate::byteorder::native_endian::U16;
1011
+ // let slice_dst_of_u8s =
1012
+ // SliceDst::<[u8; 2]>::ref_from_bytes(&[0, 1, 2, 3, 4, 5, 6][..]).unwrap();
1013
+ // let slice_dst_of_u16s =
1014
+ // SliceDst::<U16>::ref_from_bytes(&[0, 1, 2, 3, 4, 5, 6][..]).unwrap();
1015
+ // let x: &SliceDst<U16> = transmute_ref!(slice_dst_of_u8s);
1016
+ // assert_eq!(x, slice_dst_of_u16s);
1017
+
1018
+ // // Test that `transmute_ref!` works on slices in a const context and
1019
+ // // that memory is transmuted as expected.
1020
+ // const SLICE_OF_U16S: &[u16] = &[0u16, 1, 2];
1021
+ // const SLICE_OF_I16S: &[i16] = &[0i16, 1, 2];
1022
+ // let y: &[i16] = transmute_ref!(SLICE_OF_U16S);
1023
+ // assert_eq!(Y, SLICE_OF_I16S);
1024
+
1025
+ // // Test that `transmute_ref!` works on slice DSTs in a const context. We
1026
+ // // have no way of synthesizing slice DST values in a const context, so
1027
+ // // this just tests that it compiles.
1028
+ // const fn _transmute_slice_dst_ref(from: &SliceDst<[u8; 2]>) -> &SliceDst<U16> {
1029
+ // transmute_ref!(from)
1030
+ // }
1031
+
1032
+ // // Test that it's legal to transmute a reference while shrinking the
1033
+ // // lifetime (note that `X` has the lifetime `'static`).
1034
+ // let x: &[u8; 8] = transmute_ref!(X);
1035
+ // assert_eq!(*x, ARRAY_OF_U8S);
1036
+
1037
+ // // Test that `transmute_ref!` supports decreasing alignment.
1038
+ // let u = AU64(0);
1039
+ // let array = [0, 0, 0, 0, 0, 0, 0, 0];
1040
+ // let x: &[u8; 8] = transmute_ref!(&u);
1041
+ // assert_eq!(*x, array);
1042
+
1043
+ // // Test that a mutable reference can be turned into an immutable one.
1044
+ // let mut x = 0u8;
1045
+ // #[allow(clippy::useless_transmute)]
1046
+ // let y: &u8 = transmute_ref!(&mut x);
1047
+ // assert_eq!(*y, 0);
1048
+ // }
1075
1049
1076
1050
#[ test]
1077
1051
fn test_try_transmute ( ) {
@@ -1209,6 +1183,30 @@ mod tests {
1209
1183
#[ allow( clippy:: useless_transmute) ]
1210
1184
let y: & u8 = transmute_mut ! ( & mut x) ;
1211
1185
assert_eq ! ( * y, 0 ) ;
1186
+
1187
+ // Test that `transmute_mut!` works on slice DSTs in and that memory is
1188
+ // transmuted as expected.
1189
+ #[ derive( KnownLayout , Immutable , FromBytes , IntoBytes , PartialEq , Debug ) ]
1190
+ #[ repr( C ) ]
1191
+ struct SliceDst < T > {
1192
+ a : u8 ,
1193
+ b : [ T ] ,
1194
+ }
1195
+
1196
+ use crate :: byteorder:: native_endian:: U16 ;
1197
+ let mut bytes = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] ;
1198
+ let slice_dst_of_u8s = SliceDst :: < [ u8 ; 2 ] > :: mut_from_bytes ( & mut bytes[ ..] ) . unwrap ( ) ;
1199
+ let mut bytes = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] ;
1200
+ let slice_dst_of_u16s = SliceDst :: < U16 > :: mut_from_bytes ( & mut bytes[ ..] ) . unwrap ( ) ;
1201
+ let x: & mut SliceDst < U16 > = transmute_mut ! ( slice_dst_of_u8s) ;
1202
+ assert_eq ! ( x, slice_dst_of_u16s) ;
1203
+
1204
+ // Test that `transmute_mut!` works on slices that memory is transmuted
1205
+ // as expected.
1206
+ let array_of_u16s: & mut [ u16 ] = & mut [ 0u16 , 1 , 2 ] ;
1207
+ let array_of_i16s: & mut [ i16 ] = & mut [ 0i16 , 1 , 2 ] ;
1208
+ let x: & mut [ i16 ] = transmute_mut ! ( array_of_u16s) ;
1209
+ assert_eq ! ( x, array_of_i16s) ;
1212
1210
}
1213
1211
1214
1212
#[ test]
0 commit comments