@@ -57,12 +57,50 @@ use pin_init::{InPlaceWrite, Init, PinInit, ZeroableOption};
57
57
/// assert!(KVBox::<Huge>::new_uninit(GFP_KERNEL).is_ok());
58
58
/// ```
59
59
///
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
+ ///
60
72
/// # Invariants
61
73
///
62
74
/// `self.0` is always properly aligned and either points to memory allocated with `A` or, for
63
75
/// zero-sized types, is a dangling, well aligned pointer.
64
76
#[ 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
+ }
66
104
67
105
/// Type alias for [`Box`] with a [`Kmalloc`] allocator.
68
106
///
0 commit comments