@@ -57,12 +57,50 @@ use pin_init::{InPlaceWrite, Init, PinInit, ZeroableOption};
5757/// assert!(KVBox::<Huge>::new_uninit(GFP_KERNEL).is_ok());
5858/// ```
5959///
60+ /// [`Box`]es can also be used to store trait objects by coercing their type:
61+ ///
62+ /// ```
63+ /// trait FooTrait {}
64+ ///
65+ /// struct FooStruct;
66+ /// impl FooTrait for FooStruct {}
67+ ///
68+ /// let _ = KBox::new(FooStruct, GFP_KERNEL)? as KBox<dyn FooTrait>;
69+ /// # Ok::<(), Error>(())
70+ /// ```
71+ ///
6072/// # Invariants
6173///
6274/// `self.0` is always properly aligned and either points to memory allocated with `A` or, for
6375/// zero-sized types, is a dangling, well aligned pointer.
6476#[ repr( transparent) ]
65- pub struct Box < T : ?Sized , A : Allocator > ( NonNull < T > , PhantomData < A > ) ;
77+ #[ cfg_attr( CONFIG_RUSTC_HAS_COERCE_POINTEE , derive( core:: marker:: CoercePointee ) ) ]
78+ pub struct Box < #[ cfg_attr( CONFIG_RUSTC_HAS_COERCE_POINTEE , pointee) ] T : ?Sized , A : Allocator > (
79+ NonNull < T > ,
80+ PhantomData < A > ,
81+ ) ;
82+
83+ // This is to allow coercion from `Box<T, A>` to `Box<U, A>` if `T` can be converted to the
84+ // dynamically-sized type (DST) `U`.
85+ #[ cfg( not( CONFIG_RUSTC_HAS_COERCE_POINTEE ) ) ]
86+ impl < T , U , A > core:: ops:: CoerceUnsized < Box < U , A > > for Box < T , A >
87+ where
88+ T : ?Sized + core:: marker:: Unsize < U > ,
89+ U : ?Sized ,
90+ A : Allocator ,
91+ {
92+ }
93+
94+ // This is to allow `Box<U, A>` to be dispatched on when `Box<T, A>` can be coerced into `Box<U,
95+ // A>`.
96+ #[ cfg( not( CONFIG_RUSTC_HAS_COERCE_POINTEE ) ) ]
97+ impl < T , U , A > core:: ops:: DispatchFromDyn < Box < U , A > > for Box < T , A >
98+ where
99+ T : ?Sized + core:: marker:: Unsize < U > ,
100+ U : ?Sized ,
101+ A : Allocator ,
102+ {
103+ }
66104
67105/// Type alias for [`Box`] with a [`Kmalloc`] allocator.
68106///
0 commit comments