Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify object safety rules for methods striked from the vtable #965

Merged
merged 2 commits into from
Apr 1, 2021

Conversation

guswynn
Copy link
Contributor

@guswynn guswynn commented Feb 18, 2021

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

src/items/traits.md Outdated Show resolved Hide resolved
Copy link
Contributor

@Havvy Havvy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these changes make it clear at all that the methods are not part of the vtable, mainly because it causes convoluted logic. Specifically, it has the structure of:

* All assoc fns must have X (Y implies X) OR
** Not have A AND
** Be M but don't S
** OTHERWISE Zeta

I had to spend five minutes just to figure out what was trying to be said. The whole list should be reorganized to say that the associated function is dispatchable (and the criteria for that) or non-dispatchable (and again, which criteria are for that). Do you want to do that?


Unrelated to this change in particular, but it should also probably say Sized is not a supertrait instead of saying Self: Sized.

@@ -325,6 +326,7 @@ fn main() {
[RFC 255]: https://github.com/rust-lang/rfcs/blob/master/text/0255-object-safety.md
[associated items]: associated-items.md
[method]: associated-items.md#methods
[supertraits]: traits.md#supertraits
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[supertraits]: traits.md#supertraits
[supertraits]: #supertraits

@guswynn
Copy link
Contributor Author

guswynn commented Feb 20, 2021

@Havvy I agree it's somewhat convoluted. Unfortunately, the reality is that object safety is somewhat convoluted. I do like your suggestion, though it would be a sign it departure from the original rfc structure, which I am not sure if it's a constraint people want to keep or not

@Havvy
Copy link
Contributor

Havvy commented Feb 20, 2021

Keeping the original RFC structure for documentation is definitely not a constraint. If it can be improved, it should.

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

Co-authored-by: bjorn3 <bjorn3@users.noreply.github.com>
@guswynn
Copy link
Contributor Author

guswynn commented Feb 22, 2021

@Havvy let me know what you think of this change!

Copy link
Contributor

@Havvy Havvy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll approve it with my suggested edits.

The things in parenthesis should be in the Note: format, but I can do that later; especially since mixing it with a list is going to be interesting.

* [`Rc<Self>`]
* [`Arc<Self>`]
* [`Pin<P>`] where `P` is one of the types above
* All associated functions must "dispatchable from a trait object" or "explicitly non-dispatchable from a trait object":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* All associated functions must "dispatchable from a trait object" or "explicitly non-dispatchable from a trait object":
* All associated functions must either be dispatchable from a trait object or be explicitly non-dispatchable:

and
* Be a [method] that does not use `Self` except in the type of the receiver.
* All [supertraits] must also be object safe.
* It must not require `Self: Sized` (i.e. `Sized` must not be a [supertrait][supertraits])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* It must not require `Self: Sized` (i.e. `Sized` must not be a [supertrait][supertraits])
* `Sized` must not be a [supertrait][supertraits]. In other words, it must not require `Self: Sized`.

Let's avoid the latinisms like "i.e."

@Havvy
Copy link
Contributor

Havvy commented Mar 31, 2021

@guswynn Any status update on this?

@guswynn
Copy link
Contributor Author

guswynn commented Mar 31, 2021

@Havvy sorry about the delay!

@Havvy Havvy merged commit 26ad13f into rust-lang:master Apr 1, 2021
@Havvy
Copy link
Contributor

Havvy commented Apr 1, 2021

💟 Thanks!

And no worries about the delay. I know I've spent more than enough time delaying on things I've been needing to do myself.

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 14, 2021
Update books

## nomicon

1 commits in 6fe476943afd53a9a6e91f38a6ea7bb48811d8ff..8551afbb2ca6f5ea37fe58380318b209785e4e02
2021-03-10 07:28:57 +0900 to 2021-04-01 21:58:50 +0900
- Add example of thinking about Send/Sync's soundness (rust-lang/nomicon#259)

## reference

10 commits in fd97729e2d82f8b08d68a31c9bfdf0c37a7fd542..e1abb17cd94cd5a8a374b48e1bc8134a2208ed48
2021-03-28 14:29:19 -0700 to 2021-04-07 08:09:48 -0700
- Update introduction.md (rust-lang/reference#1004)
- clarify UB for raw ptr deref (rust-lang/reference#1000)
- Update lint level documentation. (rust-lang/reference#998)
- Add rustdoc to tool lints. (rust-lang/reference#997)
- Link to ptr::addr_of on raw pointer docs (rust-lang/reference#993)
- apply rust-lang/reference#950 to STYLE.md (rust-lang/reference#980)
- Tuple Passover rust-lang/reference#2 (rust-lang/reference#990)
- Fix typo in macros-by-example.md (rust-lang/reference#996)
- Clarify object safety rules for methods striked from the vtable (rust-lang/reference#965)
- Add const generic args to const contexts. (rust-lang/reference#995)

## rust-by-example

1 commits in 29d91f591c90dd18fdca6d23f1a9caf9c139d0d7..c80f0b09fc15b9251825343be910c08531938ab2
2021-03-23 09:03:39 -0300 to 2021-04-08 10:28:17 -0300
- fix compile bug with panic! (rust-lang/rust-by-example#1433)

## rustc-dev-guide

11 commits in 0687daa..a9bd2bb
2021-03-28 13:33:56 -0400 to 2021-04-09 18:12:21 -0400
- Improve formatting and update info in "method lookup" section
- Change wording a bit: `module` =&gt; `crate`
- fix typo (rust-lang/rustc-dev-guide#1107)
- fix typo
- Mention CI build of LLVM in build instruction
- Fix rustdocs test command typo (rust-lang/rustc-dev-guide#1103)
- Update the "LLVM updates" section
- Fix a link about Rustdoc internals
- Add quickstart for adding a new optimization (rust-lang/rustc-dev-guide#1094)
- Add back example of {{cwd}} (rust-lang/rustc-dev-guide#1099)
- Document test input normalization

## embedded-book

1 commits in d3f2ace94d51610cf3e3c265705bb8416d37f8e4..569c3391f5c0cc43433bc77831d17f8ff4d76602
2021-03-17 07:53:09 +0000 to 2021-04-07 08:32:11 +0000
- Make it easier to copy and paste example commands.  (rust-embedded/book#289)
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 14, 2021
Update books

## nomicon

1 commits in 6fe476943afd53a9a6e91f38a6ea7bb48811d8ff..8551afbb2ca6f5ea37fe58380318b209785e4e02
2021-03-10 07:28:57 +0900 to 2021-04-01 21:58:50 +0900
- Add example of thinking about Send/Sync's soundness (rust-lang/nomicon#259)

## reference

10 commits in fd97729e2d82f8b08d68a31c9bfdf0c37a7fd542..e1abb17cd94cd5a8a374b48e1bc8134a2208ed48
2021-03-28 14:29:19 -0700 to 2021-04-07 08:09:48 -0700
- Update introduction.md (rust-lang/reference#1004)
- clarify UB for raw ptr deref (rust-lang/reference#1000)
- Update lint level documentation. (rust-lang/reference#998)
- Add rustdoc to tool lints. (rust-lang/reference#997)
- Link to ptr::addr_of on raw pointer docs (rust-lang/reference#993)
- apply rust-lang/reference#950 to STYLE.md (rust-lang/reference#980)
- Tuple Passover rust-lang/reference#2 (rust-lang/reference#990)
- Fix typo in macros-by-example.md (rust-lang/reference#996)
- Clarify object safety rules for methods striked from the vtable (rust-lang/reference#965)
- Add const generic args to const contexts. (rust-lang/reference#995)

## rust-by-example

1 commits in 29d91f591c90dd18fdca6d23f1a9caf9c139d0d7..c80f0b09fc15b9251825343be910c08531938ab2
2021-03-23 09:03:39 -0300 to 2021-04-08 10:28:17 -0300
- fix compile bug with panic! (rust-lang/rust-by-example#1433)

## rustc-dev-guide

11 commits in 0687daa..a9bd2bb
2021-03-28 13:33:56 -0400 to 2021-04-09 18:12:21 -0400
- Improve formatting and update info in "method lookup" section
- Change wording a bit: `module` =&gt; `crate`
- fix typo (rust-lang/rustc-dev-guide#1107)
- fix typo
- Mention CI build of LLVM in build instruction
- Fix rustdocs test command typo (rust-lang/rustc-dev-guide#1103)
- Update the "LLVM updates" section
- Fix a link about Rustdoc internals
- Add quickstart for adding a new optimization (rust-lang/rustc-dev-guide#1094)
- Add back example of {{cwd}} (rust-lang/rustc-dev-guide#1099)
- Document test input normalization

## embedded-book

1 commits in d3f2ace94d51610cf3e3c265705bb8416d37f8e4..569c3391f5c0cc43433bc77831d17f8ff4d76602
2021-03-17 07:53:09 +0000 to 2021-04-07 08:32:11 +0000
- Make it easier to copy and paste example commands.  (rust-embedded/book#289)
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 14, 2021
Update books

## nomicon

1 commits in 6fe476943afd53a9a6e91f38a6ea7bb48811d8ff..8551afbb2ca6f5ea37fe58380318b209785e4e02
2021-03-10 07:28:57 +0900 to 2021-04-01 21:58:50 +0900
- Add example of thinking about Send/Sync's soundness (rust-lang/nomicon#259)

## reference

10 commits in fd97729e2d82f8b08d68a31c9bfdf0c37a7fd542..e1abb17cd94cd5a8a374b48e1bc8134a2208ed48
2021-03-28 14:29:19 -0700 to 2021-04-07 08:09:48 -0700
- Update introduction.md (rust-lang/reference#1004)
- clarify UB for raw ptr deref (rust-lang/reference#1000)
- Update lint level documentation. (rust-lang/reference#998)
- Add rustdoc to tool lints. (rust-lang/reference#997)
- Link to ptr::addr_of on raw pointer docs (rust-lang/reference#993)
- apply rust-lang/reference#950 to STYLE.md (rust-lang/reference#980)
- Tuple Passover rust-lang/reference#2 (rust-lang/reference#990)
- Fix typo in macros-by-example.md (rust-lang/reference#996)
- Clarify object safety rules for methods striked from the vtable (rust-lang/reference#965)
- Add const generic args to const contexts. (rust-lang/reference#995)

## rust-by-example

1 commits in 29d91f591c90dd18fdca6d23f1a9caf9c139d0d7..c80f0b09fc15b9251825343be910c08531938ab2
2021-03-23 09:03:39 -0300 to 2021-04-08 10:28:17 -0300
- fix compile bug with panic! (rust-lang/rust-by-example#1433)

## rustc-dev-guide

11 commits in 0687daa..a9bd2bb
2021-03-28 13:33:56 -0400 to 2021-04-09 18:12:21 -0400
- Improve formatting and update info in "method lookup" section
- Change wording a bit: `module` =&gt; `crate`
- fix typo (rust-lang/rustc-dev-guide#1107)
- fix typo
- Mention CI build of LLVM in build instruction
- Fix rustdocs test command typo (rust-lang/rustc-dev-guide#1103)
- Update the "LLVM updates" section
- Fix a link about Rustdoc internals
- Add quickstart for adding a new optimization (rust-lang/rustc-dev-guide#1094)
- Add back example of {{cwd}} (rust-lang/rustc-dev-guide#1099)
- Document test input normalization

## embedded-book

1 commits in d3f2ace94d51610cf3e3c265705bb8416d37f8e4..569c3391f5c0cc43433bc77831d17f8ff4d76602
2021-03-17 07:53:09 +0000 to 2021-04-07 08:32:11 +0000
- Make it easier to copy and paste example commands.  (rust-embedded/book#289)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants