@@ -265,9 +265,8 @@ The macro sets the following requirements on its input:
265
265
2 . The struct must have at least one type parameter. If multiple type
266
266
parameters are present, exactly one of them has to be annotated with the
267
267
` #[pointee] ` derive helper attribute.
268
- 3 . The struct must not be ` #[repr(packed)] ` or ` #[repr(C)] ` .
269
- 4 . Other than one-aligned, zero-sized fields, the struct must have exactly one
270
- field.
268
+ 3 . The struct must be ` #[repr(transparent)] ` .
269
+ 4 . The struct must have at least one field.
271
270
5 . Assume that ` T ` is a type that can be unsized to ` U ` , and let ` FT ` and ` FU `
272
271
be the type of the struct's field when the pointee is equal to ` T ` and ` U `
273
272
respectively. If the struct's trait bounds are satisfied for both ` T ` and
@@ -276,9 +275,10 @@ The macro sets the following requirements on its input:
276
275
277
276
(Adapted from the docs for [ ` DispatchFromDyn ` ] .)
278
277
279
- Point 1 and 2 are verified syntactically by the derive macro, whereas 3, 4 and 5
278
+ Point 1 and 2 are verified syntactically by the derive macro. Points 4 and 5
280
279
are verified semantically by the compiler when checking the generated
281
- [ ` DispatchFromDyn ` ] implementation as it does today.
280
+ [ ` DispatchFromDyn ` ] implementation as it does today. Point 3 is verified by
281
+ introducing a new unstable helper trait ` AssertReprTransparent ` .
282
282
283
283
The ` #[pointee] ` attribute may also be written as ` #[smart_pointer::pointee] ` .
284
284
@@ -331,6 +331,16 @@ where
331
331
T : :: core :: marker :: Unsize <U >,
332
332
{}
333
333
```
334
+ The macro will also generate an implementation of the new
335
+ ` AssertReprTransparent ` helper trait. The implementation will have the same
336
+ trait bounds as the struct definition.
337
+ ``` rust
338
+ #[automatically_derived]
339
+ impl <'a , T , A > :: core :: ops :: AssertReprTransparent for MySmartPointer <'a , T , A >
340
+ where
341
+ T : ? Sized + SomeTrait <T >,
342
+ {}
343
+ ```
334
344
335
345
## ` Receiver ` and ` Deref ` implementations
336
346
@@ -390,6 +400,13 @@ Although this RFC proposes to add the `PinCoerceUnsized` trait to ensure that
390
400
unsizing coercions of pinned pointers cannot be used to cause unsoundness, the
391
401
RFC does not propose to stabilize the trait.
392
402
403
+ ## ` AssertReprTransparent `
404
+
405
+ To verify the requirement that the struct is ` #[repr(transparent)] ` , we
406
+ introduce a new unstable marker trait called ` AssertReprTransparent ` . This trait
407
+ will be a lang item, and the compiler will emit an error if the trait is used
408
+ with a type that is not ` #[repr(transparent)] ` .
409
+
393
410
# Drawbacks
394
411
[ drawbacks ] : #drawbacks
395
412
@@ -715,6 +732,27 @@ This RFC does not propose it because it is a breaking change and the
715
732
discussed in more details in [ the pre-RFC for stabilizing the underlying
716
733
traits] [ pre-rfc ] .
717
734
735
+ ## ` AssertReprTransparent `
736
+
737
+ When you implement the [ ` DispatchFromDyn ` ] trait, the compiler enforces various
738
+ things about the type to verify that it makes sense to implement
739
+ ` DispatchFromDyn ` . One of the things that the compiler verifies is that the
740
+ struct must not be ` #[repr(packed)] ` or ` #[repr(C)] ` .
741
+
742
+ However, because ` #[derive(SmartPointer)] ` has more narrow use-case than
743
+ ` DispatchFromDyn ` , we would like to restrict it further so that the macro only
744
+ works with ` #[repr(transparent)] ` types. To do this, we use a new trait called
745
+ ` AssertReprTransparent ` that verifies that the struct is ` #[repr(transparent)] `
746
+ like how ` DispatchFromDyn ` verifies that the struct must not be
747
+ ` #[repr(packed)] ` or ` #[repr(C)] ` .
748
+
749
+ We cannot change the logic in ` DispatchFromDyn ` because some existing standard
750
+ library types cannot be ` #[repr(transparent)] ` . For example, this includes
751
+ ` Box<T, A> ` due to its allocator field.
752
+
753
+ This requirement may be relaxed in the future, in which case
754
+ ` AssertReprTransparent ` can be removed again.
755
+
718
756
# Prior art
719
757
[ prior-art ] : #prior-art
720
758
0 commit comments