@@ -216,14 +216,15 @@ macro_rules! impl_for_transparent_wrapper {
216
216
// - `f` can only compile if its internal call to
217
217
// `is_transparent_wrapper` compiles.
218
218
//
219
- // The definition of `is_transparent_wrapper` is generated by each
220
- // `@is_transparent_wrapper` macro arm. Each arm is parameterized by
221
- // `$trait`, and emits bounds which are sufficient to ensure that this
222
- // is a sound implementation of `$trait for $ty` *so long as* `$tyvar:
223
- // $trait`. Note that we require `$tyvar: $trait` in the `impl` block
224
- // itself. Thus, so long as the bounds emitted by the
225
- // `@is_transparent_wrapper` arm are sound, then this entire impl is
226
- // sound.
219
+ // The definition of `is_transparent_wrapper<I, T, W>` is generated by
220
+ // each `@is_transparent_wrapper` macro arm. Each arm is parameterized
221
+ // by `$trait`, and emits bounds which are sufficient to ensure that
222
+ // this is a sound implementation of `$trait for W` *so long as* `T:
223
+ // $trait`. In `f`, we call `is_transparent_wrapper<I, $tyvar, $ty>`,
224
+ // and so if this code compiles, that guarantees that `$ty` satisfies
225
+ // the same bounds for all `$tyvar: $trait`. Thus, so long as the bounds
226
+ // emitted by the `@is_transparent_wrapper` arm are sound, then this
227
+ // entire impl is sound.
227
228
//
228
229
// Each `@is_transparent_wrapper` arm contains its own safety comment
229
230
// which explains why its bounds are sound.
@@ -241,11 +242,61 @@ macro_rules! impl_for_transparent_wrapper {
241
242
242
243
impl_for_transparent_wrapper!(
243
244
@is_bit_valid
244
- $tyvar: $( $( ? $optbound +) * $( $bound +) * ) ?
245
- => $trait for $ty
245
+ < $tyvar: $( $( ? $optbound +) * $( $bound +) * ) ?>
246
+ $trait for $ty
246
247
) ;
247
248
}
248
249
} ;
250
+ (
251
+ $( #[ $attr: meta] ) *
252
+ for $ty: ty [ $inner: ty] $( ; |$candidate: ident $( : MaybeAligned <$ref_repr: ty>) ? $( : Maybe <$ptr_repr: ty>) ?| $is_bit_valid: expr) ?
253
+ ) => { } ;
254
+ (
255
+ $( #[ $attr: meta] ) *
256
+ $trait: ident $( , $traits: ident) * for $ty: ty [ $inner: ty] $( ; |$candidate: ident $( : MaybeAligned <$ref_repr: ty>) ? $( : Maybe <$ptr_repr: ty>) ?| $is_bit_valid: expr) ?
257
+ ) => {
258
+ impl_for_transparent_wrapper!(
259
+ $( #[ $attr] ) *
260
+ $( $traits) ,* for $ty [ $inner] $( ; |$candidate $( : MaybeAligned <$ref_repr>) ? $( : Maybe <$ptr_repr>) ?| $is_bit_valid: expr) ?
261
+ ) ;
262
+
263
+ $( #[ $attr] ) *
264
+ #[ allow( non_local_definitions) ]
265
+ // SAFETY:
266
+ // - We explicitly add a `$tyvar: $trait` bound (regardless of what
267
+ // bounds the caller has provided).
268
+ // - Inside of `only_derive_is_allowed_to_implement_this_trait`, `f` is
269
+ // generic over the any `I: Invariants`.
270
+ // - `f` can only compile if its internal call to
271
+ // `is_transparent_wrapper` compiles.
272
+ //
273
+ // The definition of `is_transparent_wrapper<I, T, W>` is generated by
274
+ // each `@is_transparent_wrapper` macro arm. Each arm is parameterized
275
+ // by `$trait`, and emits bounds which are sufficient to ensure that
276
+ // this is a sound implementation of `$trait for W` *so long as* `T:
277
+ // $trait`. In `f`, we call `is_transparent_wrapper<I, $inner, $ty>`,
278
+ // and so if this code compiles, that guarantees that `$ty` satisfies
279
+ // the same bounds so long as `$inner: $trait`. Thus, so long as the
280
+ // bounds emitted by the `@is_transparent_wrapper` arm are sound, then
281
+ // this entire impl is sound.
282
+ //
283
+ // Each `@is_transparent_wrapper` arm contains its own safety comment
284
+ // which explains why its bounds are sound.
285
+ unsafe impl $trait for $ty {
286
+ #[ allow( dead_code, clippy:: missing_inline_in_public_items) ]
287
+ fn only_derive_is_allowed_to_implement_this_trait( ) {
288
+ use crate :: { pointer:: invariant:: Invariants , util:: * } ;
289
+
290
+ impl_for_transparent_wrapper!( @is_transparent_wrapper $trait) ;
291
+
292
+ fn f<I : Invariants >( ) {
293
+ is_transparent_wrapper:: <I , $inner, $ty>( ) ;
294
+ }
295
+ }
296
+
297
+ impl_for_transparent_wrapper!( @is_bit_valid $trait for $ty) ;
298
+ }
299
+ } ;
249
300
( @is_transparent_wrapper NoCell ) => {
250
301
// SAFETY: `W: TransparentWrapper<UnsafeCellVariance=Covariant>`
251
302
// requires that `W` has `UnsafeCell`s at the same byte offsets as
@@ -299,8 +350,8 @@ macro_rules! impl_for_transparent_wrapper {
299
350
} ;
300
351
(
301
352
@is_bit_valid
302
- $tyvar: ident $( : $( ? $optbound: ident $( +) ?) * $( $bound: ident $( +) ?) * ) ?
303
- => TryFromBytes for $ty: ty
353
+ $( <$ tyvar: ident $( : $( ? $optbound: ident $( +) ?) * $( $bound: ident $( +) ?) * ) ?> ) ?
354
+ TryFromBytes for $ty: ty
304
355
) => {
305
356
// SAFETY: See safety comment in `(@is_transparent_wrapper
306
357
// TryFromBytes)` macro arm for an explanation of why this is a sound
@@ -312,8 +363,8 @@ macro_rules! impl_for_transparent_wrapper {
312
363
} ;
313
364
(
314
365
@is_bit_valid
315
- $tyvar: ident $( : $( ? $optbound: ident $( +) ?) * $( $bound: ident $( +) ?) * ) ?
316
- => $trait: ident for $ty: ty
366
+ $( <$ tyvar: ident $( : $( ? $optbound: ident $( +) ?) * $( $bound: ident $( +) ?) * ) ?> ) ?
367
+ $trait: ident for $ty: ty
317
368
) => {
318
369
// Trait other than `TryFromBytes`; no `is_bit_valid` impl.
319
370
} ;
@@ -553,15 +604,14 @@ macro_rules! unsafe_impl_known_layout {
553
604
/// Note that `align_of<T>` requires `T: Sized`, so this macro doesn't work for
554
605
/// unsized types.
555
606
macro_rules! assert_unaligned {
556
- ( $ty: ty) => {
557
- // We only compile this assertion under `cfg(test)` to avoid taking an
558
- // extra non-dev dependency (and making this crate more expensive to
559
- // compile for our dependents).
560
- #[ cfg( test) ]
561
- static_assertions:: const_assert_eq!( core:: mem:: align_of:: <$ty>( ) , 1 ) ;
562
- } ;
563
- ( $( $ty: ty) ,* ) => {
564
- $( assert_unaligned!( $ty) ; ) *
607
+ ( $( $tys: ty) ,* ) => {
608
+ $(
609
+ // We only compile this assertion under `cfg(test)` to avoid taking
610
+ // an extra non-dev dependency (and making this crate more expensive
611
+ // to compile for our dependents).
612
+ #[ cfg( test) ]
613
+ static_assertions:: const_assert_eq!( core:: mem:: align_of:: <$tys>( ) , 1 ) ;
614
+ ) *
565
615
} ;
566
616
}
567
617
0 commit comments