@@ -393,6 +393,38 @@ Note that having the macro generate a `Receiver` impl instead doesn't work
393
393
either, because that prevents the user from implementing ` Deref ` at all. (There
394
394
is a blanket impl of ` Receiver ` for all ` Deref ` types.)
395
395
396
+ ## Transparent containers
397
+
398
+ Smart pointers are not the only use case for implementing the [ ` CoerceUnsized ` ]
399
+ and [ ` DispatchFromDyn ` ] traits. They are also used for "transparent containers"
400
+ such as [ ` Cell ` ] . That use-case allows coercions such as ` Cell<Box<MyStruct>> `
401
+ to ` Cell<Box<dyn MyTrait>> ` . (Coercions where the ` Cell ` is inside the ` Box ` are
402
+ already supported on stable Rust.)
403
+
404
+ It is not possible to use the derive macro proposed by this RFC for transparent
405
+ containers because they require a different set of where bounds when
406
+ implementing the traits. To compare:
407
+ ``` rust
408
+ // smart pointer example
409
+ impl <T , U > DispatchFromDyn <Box <U >> for Box <T >
410
+ where
411
+ T : Unsize <U > + ? Sized ,
412
+ U : ? Sized ,
413
+ {}
414
+
415
+ // transparent container example
416
+ impl <T , U > DispatchFromDyn <Cell <U >> for Cell <T >
417
+ where
418
+ T : DispatchFromDyn <U >,
419
+ {}
420
+ ```
421
+ Attempting to annotate ` #[derive(SmartPointer)] ` onto a transparent container
422
+ will fail to compile because [ it violates the rules for implementing
423
+ ` DispatchFromDyn ` ] [ tc-pg ] . Supporting custom transparent containers is out of
424
+ scope for this RFC.
425
+
426
+ [ tc-pg ] : https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=c3fe2a11822e4c5e2dae5bfec9d77b9e
427
+
396
428
## Why not two derive macros?
397
429
398
430
The derive macro generates two different trait implementations:
@@ -406,21 +438,16 @@ It could be argued that these should be split into two separate derive macros.
406
438
We are not proposing this for a few reasons:
407
439
408
440
- If there are two derive macros, then we have to support the case where you
409
- only use one of them. There are use-cases for implementing [ ` CoerceUnsized ` ]
410
- without [ ` DispatchFromDyn ` ] , but you do this for cases where your type is not
411
- a smart pointer, but rather a transparent container like [ ` Cell ` ] . It makes
412
- coercions like ` Cell<Box<MyStruct>> ` to ` Cell<Box<dyn MyTrait>> ` possible.
413
- Supporting that is a significantly increased scope of the RFC, and the
414
- authors believe that supporting transparent containers should be a separate
415
- follow-up RFC.
416
-
417
- - Right now there are use cases for ` CoerceUnsized ` (transparent containers)
418
- and ` CoerceUnsized+DispatchFromDyn ` (smart pointers), but there aren't any
419
- real use-cases for having ` DispatchFromDyn ` alone. Because of that, one
420
- possible future design of the underlying traits could be to have one trait
421
- for smart pointers, and another one for transparent containers. Adding two
422
- derive macros prevents us from changing the underlying traits to that design
423
- in the future.
441
+ only use one of them. There isn't much reason to do that, and the authors are
442
+ not aware of any examples where you would prefer to implement one of the
443
+ traits without implementing both.
444
+
445
+ - Having two different macros means that we lock ourselves into solutions that
446
+ involve two traits that split the feature in the way that we split it today.
447
+ However, it is easy to imagine situations where we would want to split the
448
+ traits in a different way. For example, we might instead want one trait for
449
+ smart pointers, and another trait for transparent containers. Or maybe we just
450
+ want one trait that does both things.
424
451
425
452
- The authors believe that a convenience ` #[derive(SmartPointer)] ` macro will
426
453
continue to make sense, even once the underlying traits are stabilized. It is
@@ -643,8 +670,9 @@ can evolve. The authors hope that we will find a way to stabilize the
643
670
underlying traits in the future.
644
671
645
672
One of the things that is left out of scope of this RFC is coercions involving
646
- custom transparent containers similar to [ ` Cell ` ] . They require an
647
- implementation of [ ` CoerceUnsized ` ] without [ ` DispatchFromDyn ` ] .
673
+ custom transparent containers similar to [ ` Cell ` ] . They require you to implement
674
+ the traits with different where bounds. Adding support for custom transparent
675
+ containers makes sense as a future expansion of the feature.
648
676
649
677
There is a reasonable change that we may be able to lift some of [ the
650
678
restrictions] [ input-requirements ] on the shape of the struct as well. The
0 commit comments