Skip to content

Commit 211abb3

Browse files
committed
Adjust how the macro expands trait bounds
Without this adjustment, it would not be possible to use this macro with types such as the `ARef` type that was discussed on the RFC thread [1], since we need `AlwaysRefcounted` to be specified for both T and U. Link: https://www.github.com/rust-lang/rfcs/pull/3621#issuecomment-2094094231 [1]
1 parent 8f029b2 commit 211abb3

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

text/3621-derive-smart-pointer.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,20 +270,25 @@ The macro will expand to two implementations, one for
270270
[`core::ops::CoerceUnsized`] and one for [`core::ops::DispatchFromDyn`]. This
271271
is enough for a type to participate in unsizing coercions and dynamic dispatch.
272272

273-
The derive macro will implement the traits for the type according to the
273+
The derive macro will implement both traits for the type according to the
274274
following procedure:
275275

276-
- Copy all generic parameters and their bounds from the struct definition into
277-
the impl.
278-
- Add an additional type parameter `U` and give it a `?Sized` bound.
276+
- Copy all generic parameters from the struct definition into the impl.
277+
- Add an additional type parameter `U`.
278+
- For every trait bound declared on the trait, add it twice to the trait
279+
implementation. Once exactly as written, and once with every instance of the
280+
`#[pointee]` parameter replaced with `U`.
279281
- Add an additional `Unsize<U>` bound to the `#[pointee]` type parameter.
280-
- The generic parameter of the traits being implemented will be `Self`, except
282+
- The generic parameter of the trait being implemented will be `Self`, except
281283
that the `#[pointee]` type parameter is replaced with `U`.
282284

283285
Given the following example code:
284286
```rust
285287
#[derive(SmartPointer)]
286-
struct MySmartPointer<'a, #[pointee] T: ?Sized, A>{
288+
struct MySmartPointer<'a, #[pointee] T, A>
289+
where
290+
T: ?Sized + SomeTrait<T>,
291+
{
287292
ptr: &'a T,
288293
phantom: PhantomData<A>,
289294
}
@@ -295,15 +300,17 @@ we'll get the following expansion:
295300
#[automatically_derived]
296301
impl<'a, T, A, U> ::core::ops::CoerceUnsized<MySmartPointer<'a, U, A>> for MySmartPointer<'a, T, A>
297302
where
298-
T: ?Sized + ::core::marker::Unsize<U>,
299-
U: ?::core::marker::Sized,
303+
T: ?Sized + SomeTrait<T>,
304+
U: ?Sized + SomeTrait<U>,
305+
T: ::core::marker::Unsize<U>,
300306
{}
301307

302308
#[automatically_derived]
303309
impl<'a, T, A, U> ::core::ops::DispatchFromDyn<MySmartPointer<'a, U, A>> for MySmartPointer<'a, T, A>
304310
where
305-
T: ?Sized + ::core::marker::Unsize<U>,
306-
U: ?::core::marker::Sized,
311+
T: ?Sized + SomeTrait<T>,
312+
U: ?Sized + SomeTrait<U>,
313+
T: ::core::marker::Unsize<U>,
307314
{}
308315
```
309316

0 commit comments

Comments
 (0)