Skip to content

Commit a5d1581

Browse files
authored
Clarify object safety rules for methods striked from the vtable
When trying to figure out how `async_trait` object safety worked and thinking about `Stream::next`'s object safety, I found it very hard to understand This clarifies that object-safety can still be possible even if a method is striked from the vtable, and that `self` and `where `Self: Sized` are the ONLY ways to do that. This was only really explained clearly in the examples below, so this includes this clarification in the object safety rules in the beginning of the section --- Separately, NonDispatchable seems like you are out of luck, but this pattern: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5529e6424895cccda19d4dd81f389b69, where we impl the trait for &T where T: Trait + ?Sized is actually quite common in the std (albeit with `self` parameter's so you don't need the `(&obj_ref)` dance to get method resolution to be happy, see https://rust-lang.zulipchat.com/#narrow/stream/249502-wg-async-foundations.2Fstream-trait-rfc/topic/Object.20safety/near/226749056 for more info). This seems like a pattern we should explain somewhere, but is the reference the right place for it? I have not mentioned it in this PR, but would be curious what people think
1 parent 361367c commit a5d1581

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

src/items/traits.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,14 @@ Object safe traits can be the base trait of a [trait object]. A trait is
6868
*object safe* if it has the following qualities (defined in [RFC 255]):
6969

7070
* It must not require `Self: Sized`
71-
* All associated functions must either have a `where Self: Sized` bound, or
71+
* All associated functions must either have a `where Self: Sized` bound
72+
(reciever type of `self: Self`implies this), or
7273
* Not have any type parameters (although lifetime parameters are allowed),
7374
and
7475
* Be a [method] that does not use `Self` except in the type of the receiver.
76+
* otherwise this method is non-dispatchable from a trait object
7577
* It must not have any associated constants.
76-
* All supertraits must also be object safe.
78+
* All [supertraits] must also be object safe.
7779

7880
When there isn't a `Self: Sized` bound on a method, the type of a method
7981
receiver must be one of the following types:
@@ -322,9 +324,10 @@ fn main() {
322324
[_WhereClause_]: generics.md#where-clauses
323325
[bounds]: ../trait-bounds.md
324326
[trait object]: ../types/trait-object.md
325-
[RFC 255]: https://github.com/rust-lang/rfcs/blob/master/text/0255-object-safety.md
327+
[RFC 255]: https://github.com/rust-lang/rfcs/blob/master/text/0255-object-.md
326328
[associated items]: associated-items.md
327329
[method]: associated-items.md#methods
330+
[supertraits]: traits.md#supertraits
328331
[implementations]: implementations.md
329332
[generics]: generics.md
330333
[where clauses]: generics.md#where-clauses

0 commit comments

Comments
 (0)