@@ -71,7 +71,8 @@ Object safe traits can be the base trait of a [trait object]. A trait is
7171* ` Sized ` must not be a [ supertrait] [ supertraits ] . In other words, it must not require ` Self: Sized ` .
7272* It must not have any associated constants.
7373* It must not have any associated types with generics.
74- * All associated functions must either be dispatchable from a trait object or be explicitly non-dispatchable:
74+ * All associated functions must either be dispatchable from a trait object,
75+ or be explicitly or implicitly non-dispatchable
7576 * Dispatchable functions must:
7677 * Not have any type parameters (although lifetime parameters are allowed).
7778 * Be a [ method] that does not use ` Self ` except in the type of the receiver.
@@ -81,13 +82,26 @@ Object safe traits can be the base trait of a [trait object]. A trait is
8182 * [ ` Box<Self> ` ]
8283 * [ ` Rc<Self> ` ]
8384 * [ ` Arc<Self> ` ]
84- * [ ` Pin<P> ` ] where ` P ` is one of the types above
85+ * [ ` Pin<P> ` ] where ` P ` is one of the types in this list (this applies recursively)
8586 * Not have an opaque return type; that is,
8687 * Not be an ` async fn ` (which has a hidden ` Future ` type).
8788 * Not have a return position ` impl Trait ` type (` fn example(&self) -> impl Trait ` ).
88- * Not have a ` where Self: Sized ` bound (receiver type of ` Self ` (i.e. ` self ` ) implies this).
89- * Explicitly non-dispatchable functions require:
90- * Have a ` where Self: Sized ` bound (receiver type of ` Self ` (i.e. ` self ` ) implies this).
89+ * Not have a ` where Self: Sized ` bound.
90+ * Explicitly non-dispatchable functions must:
91+ * Have a ` where Self: Sized ` bound.
92+ * Implicitly non-dispatchable functions must:
93+ * Have the receiver type ` Self ` (i.e. ` self ` )
94+ * Fulfill all the conditions of dispatchable functions, except for the receiver type.
95+
96+ Methods with ` Self ` receiver type are implicitly non-dispatchable
97+ (“non-dispatchable” means that they cannot be called on trait object types), but
98+ [ might become dispatchable in future versions of Rust] ( https://github.com/rust-lang/rust/issues/48055 ) .
99+ Currently, unsized function arguments are not supported in Rust, so such methods cannot be
100+ implemented for unsized types, which means providing a function body as default implementation
101+ for the method is not possible, nor are (manual) implementations of the trait for unsized types
102+ possible. Implicitly non-dispatchable methods serve the future-compatibility of your trait,
103+ if unsized function arguments become supported in future versions of Rust,
104+ as removing an explicit ` Self: Sized ` bound later would constitute a semver-breaking API change.
91105
92106``` rust
93107# use std :: rc :: Rc ;
@@ -120,16 +134,23 @@ trait NonDispatchable {
120134 fn param(&self, other: Self) where Self: Sized {}
121135 // Generics are not compatible with vtables.
122136 fn typed<T>(&self, x: T) where Self: Sized {}
137+ // `self: Self` functions cannot be dispatched,
138+ // but this mighty change in the future
139+ fn by_value(self); // default implementation is not supported
123140}
124141
125142struct S;
126143impl NonDispatchable for S {
127144 fn returns(&self) -> Self where Self: Sized { S }
145+ fn by_value(self) {}
128146}
129147let obj: Box<dyn NonDispatchable> = Box::new(S);
130- obj.returns(); // ERROR: cannot call with Self return
131- obj.param(S); // ERROR: cannot call with Self parameter
132- obj.typed(1); // ERROR: cannot call with generic type
148+ // `dyn NonDispatchable` is a dynamically sized type
149+ // and does not implement the `Sized` trait
150+ obj.returns(); // ERROR: cannot call the function due to its `Self: Sized` bound
151+ obj.param(S); // ERROR: cannot call the function due to its `Self: Sized` bound
152+ obj.typed(1); // ERROR: cannot call the function due to its `Self: Sized` bound
153+ obj.by_value(); // ERROR: cannot call functions with dynamically sized arguments
133154```
134155
135156``` rust,compile_fail
@@ -162,8 +183,8 @@ let obj: Box<dyn TraitWithSize> = Box::new(S); // ERROR
162183
163184``` rust,compile_fail
164185// Not object safe if `Self` is a type argument.
165- trait Super<A> {}
166- trait WithSelf: Super<Self> where Self: Sized {}
186+ trait Super<A: ?Sized > {}
187+ trait WithSelf: Super<Self> {}
167188
168189struct S;
169190impl<A> Super<A> for S {}
0 commit comments