@@ -71,7 +71,8 @@ Object safe traits can be the base trait of a [trait object]. A trait is
71
71
* ` Sized ` must not be a [ supertrait] [ supertraits ] . In other words, it must not require ` Self: Sized ` .
72
72
* It must not have any associated constants.
73
73
* 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
75
76
* Dispatchable functions must:
76
77
* Not have any type parameters (although lifetime parameters are allowed).
77
78
* 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
81
82
* [ ` Box<Self> ` ]
82
83
* [ ` Rc<Self> ` ]
83
84
* [ ` 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)
85
86
* Not have an opaque return type; that is,
86
87
* Not be an ` async fn ` (which has a hidden ` Future ` type).
87
88
* 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.
91
105
92
106
``` rust
93
107
# use std :: rc :: Rc ;
@@ -120,16 +134,23 @@ trait NonDispatchable {
120
134
fn param(&self, other: Self) where Self: Sized {}
121
135
// Generics are not compatible with vtables.
122
136
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
123
140
}
124
141
125
142
struct S;
126
143
impl NonDispatchable for S {
127
144
fn returns(&self) -> Self where Self: Sized { S }
145
+ fn by_value(self) {}
128
146
}
129
147
let 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
133
154
```
134
155
135
156
``` rust,compile_fail
@@ -162,8 +183,8 @@ let obj: Box<dyn TraitWithSize> = Box::new(S); // ERROR
162
183
163
184
``` rust,compile_fail
164
185
// 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> {}
167
188
168
189
struct S;
169
190
impl<A> Super<A> for S {}
0 commit comments