@@ -95,6 +95,99 @@ Object safe traits can be the base trait of a [trait object]. A trait is
95
95
* It must not have any associated constants.
96
96
* All supertraits must also be object safe.
97
97
98
+ When there isn't a ` Self: Sized ` bound on a method, the type of a method
99
+ receiver must be one of the following types:
100
+
101
+ * ` &Self `
102
+ * ` &mut Self `
103
+ * [ ` Box<Self> ` ]
104
+ * [ ` Rc<Self> ` ]
105
+ * [ ` Arc<Self> ` ]
106
+ * [ ` Pin<P> ` ] where ` P ` is one of the types above
107
+
108
+ ``` rust
109
+ # use std :: rc :: Rc ;
110
+ # use std :: sync :: Arc ;
111
+ # use std :: pin :: Pin ;
112
+ // Examples of object safe methods.
113
+ trait TraitMethods {
114
+ fn by_ref (self : & Self ) {}
115
+ fn by_ref_mut (self : & mut Self ) {}
116
+ fn by_box (self : Box <Self >) {}
117
+ fn by_rc (self : Rc <Self >) {}
118
+ fn by_arc (self : Arc <Self >) {}
119
+ fn by_pin (self : Pin <& Self >) {}
120
+ fn with_lifetime <'a >(self : & 'a Self ) {}
121
+ fn nested_pin (self : Pin <Arc <Self >>) {}
122
+ }
123
+ # struct S ;
124
+ # impl TraitMethods for S {}
125
+ # let t : Box <dyn TraitMethods > = Box :: new (S );
126
+ ```
127
+
128
+ ``` rust,compile_fail
129
+ // These are object-safe, but cannot be dispatched on a trait object.
130
+ trait NonDispatchable {
131
+ // Non-methods cannot be dispatched.
132
+ fn foo() where Self: Sized {}
133
+ // Self type isn't known until runtime.
134
+ fn returns(&self) -> Self where Self: Sized;
135
+ // `other` may be a different concrete type of the receiver.
136
+ fn param(&self, other: Self) where Self: Sized {}
137
+ // Generics are not compatible with vtables.
138
+ // Alternate solution is to use a trait object instead.
139
+ fn typed<T>(&self, x: T) where Self: Sized {}
140
+ }
141
+
142
+ struct S;
143
+ impl NonDispatchable for S {
144
+ fn returns(&self) -> Self where Self: Sized { S }
145
+ }
146
+ let obj: Box<dyn NonDispatchable> = Box::new(S);
147
+ obj.returns(); // ERROR: cannot call with Self return
148
+ obj.param(S); // ERROR: cannot call with Self parameter
149
+ obj.typed(1); // ERROR: cannot call with generic type
150
+ ```
151
+
152
+ ``` rust,compile_fail
153
+ # use std::rc::Rc;
154
+ // Examples of non-object safe traits.
155
+ trait NotObjectSafe {
156
+ const CONST: i32 = 1; // ERROR: cannot have associated const
157
+
158
+ fn foo() {} // ERROR: associated function without Sized
159
+ fn returns(&self) -> Self; // ERROR: Self in return type
160
+ fn typed<T>(&self, x: T) {} // ERROR: has generic type parameters
161
+ fn nested(self: Rc<Box<Self>>) {} // ERROR: nested receiver not yet supported
162
+ }
163
+
164
+ struct S;
165
+ impl NotObjectSafe for S {
166
+ fn returns(&self) -> Self { S }
167
+ }
168
+ let obj: Box<dyn NotObjectSafe> = Box::new(S); // ERROR
169
+ ```
170
+
171
+ ``` rust,compile_fail
172
+ // Self: Sized traits are not object-safe.
173
+ trait TraitWithSize where Self: Sized {}
174
+
175
+ struct S;
176
+ impl TraitWithSize for S {}
177
+ let obj: Box<dyn TraitWithSize> = Box::new(S); // ERROR
178
+ ```
179
+
180
+ ``` rust,compile_fail
181
+ // Not object safe if `Self` is a type parameter.
182
+ trait Super<A> {}
183
+ trait WithSelf: Super<Self> where Self: Sized {}
184
+
185
+ struct S;
186
+ impl<A> Super<A> for S {}
187
+ impl WithSelf for S {}
188
+ let obj: Box<dyn WithSelf> = Box::new(S); // ERROR: cannot use `Self` type parameter
189
+ ```
190
+
98
191
## Supertraits
99
192
100
193
** Supertraits** are traits that are required to be implemented for a type to
@@ -231,3 +324,7 @@ trait T {
231
324
[ trait implementation ] : implementations.md#trait-implementations
232
325
[ `Send` ] : ../special-types-and-traits.md#send
233
326
[ `Sync` ] : ../special-types-and-traits.md#sync
327
+ [ `Arc<Self>` ] : ../special-types-and-traits.md#arct
328
+ [ `Box<Self>` ] : ../special-types-and-traits.md#boxt
329
+ [ `Pin<P>` ] : ../special-types-and-traits.md#pinp
330
+ [ `Rc<Self>` ] : ../special-types-and-traits.md#rct
0 commit comments