@@ -95,6 +95,98 @@ Object safe traits can be the base trait of a [trait object]. A trait is
9595* It must not have any associated constants.
9696* All supertraits must also be object safe.
9797
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+ // This trait is object-safe, but these methods 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+ fn typed<T>(&self, x: T) where Self: Sized {}
139+ }
140+
141+ struct S;
142+ impl NonDispatchable for S {
143+ fn returns(&self) -> Self where Self: Sized { S }
144+ }
145+ let obj: Box<dyn NonDispatchable> = Box::new(S);
146+ obj.returns(); // ERROR: cannot call with Self return
147+ obj.param(S); // ERROR: cannot call with Self parameter
148+ obj.typed(1); // ERROR: cannot call with generic type
149+ ```
150+
151+ ``` rust,compile_fail
152+ # use std::rc::Rc;
153+ // Examples of non-object safe traits.
154+ trait NotObjectSafe {
155+ const CONST: i32 = 1; // ERROR: cannot have associated const
156+
157+ fn foo() {} // ERROR: associated function without Sized
158+ fn returns(&self) -> Self; // ERROR: Self in return type
159+ fn typed<T>(&self, x: T) {} // ERROR: has generic type parameters
160+ fn nested(self: Rc<Box<Self>>) {} // ERROR: nested receiver not yet supported
161+ }
162+
163+ struct S;
164+ impl NotObjectSafe for S {
165+ fn returns(&self) -> Self { S }
166+ }
167+ let obj: Box<dyn NotObjectSafe> = Box::new(S); // ERROR
168+ ```
169+
170+ ``` rust,compile_fail
171+ // Self: Sized traits are not object-safe.
172+ trait TraitWithSize where Self: Sized {}
173+
174+ struct S;
175+ impl TraitWithSize for S {}
176+ let obj: Box<dyn TraitWithSize> = Box::new(S); // ERROR
177+ ```
178+
179+ ``` rust,compile_fail
180+ // Not object safe if `Self` is a type argument.
181+ trait Super<A> {}
182+ trait WithSelf: Super<Self> where Self: Sized {}
183+
184+ struct S;
185+ impl<A> Super<A> for S {}
186+ impl WithSelf for S {}
187+ let obj: Box<dyn WithSelf> = Box::new(S); // ERROR: cannot use `Self` type parameter
188+ ```
189+
98190## Supertraits
99191
100192** Supertraits** are traits that are required to be implemented for a type to
@@ -268,3 +360,7 @@ fn main() {
268360[ trait implementation ] : implementations.md#trait-implementations
269361[ `Send` ] : ../special-types-and-traits.md#send
270362[ `Sync` ] : ../special-types-and-traits.md#sync
363+ [ `Arc<Self>` ] : ../special-types-and-traits.md#arct
364+ [ `Box<Self>` ] : ../special-types-and-traits.md#boxt
365+ [ `Pin<P>` ] : ../special-types-and-traits.md#pinp
366+ [ `Rc<Self>` ] : ../special-types-and-traits.md#rct
0 commit comments