@@ -265,9 +265,8 @@ The macro sets the following requirements on its input:
2652652 . The struct must have at least one type parameter. If multiple type
266266 parameters are present, exactly one of them has to be annotated with the
267267 ` #[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.
2712705 . Assume that ` T ` is a type that can be unsized to ` U ` , and let ` FT ` and ` FU `
272271 be the type of the struct's field when the pointee is equal to ` T ` and ` U `
273272 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:
276275
277276(Adapted from the docs for [ ` DispatchFromDyn ` ] .)
278277
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
280279are 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 ` .
282282
283283The ` #[pointee] ` attribute may also be written as ` #[smart_pointer::pointee] ` .
284284
@@ -331,6 +331,16 @@ where
331331 T : :: core :: marker :: Unsize <U >,
332332{}
333333```
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+ ```
334344
335345## ` Receiver ` and ` Deref ` implementations
336346
@@ -390,6 +400,13 @@ Although this RFC proposes to add the `PinCoerceUnsized` trait to ensure that
390400unsizing coercions of pinned pointers cannot be used to cause unsoundness, the
391401RFC does not propose to stabilize the trait.
392402
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+
393410# Drawbacks
394411[ drawbacks ] : #drawbacks
395412
@@ -715,6 +732,27 @@ This RFC does not propose it because it is a breaking change and the
715732discussed in more details in [ the pre-RFC for stabilizing the underlying
716733traits] [ pre-rfc ] .
717734
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+
718756# Prior art
719757[ prior-art ] : #prior-art
720758
0 commit comments