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

Document how self: Self receiver types *actually* interact with object safety #1455

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

steffahn
Copy link
Member

@steffahn steffahn commented Jan 26, 2024

Fixes #1247

The description here on how this works is based purely on experiments on what the compiler does or does not accept (without unstable features), not on any inspection of the implementation in rustc. The term of “implicitly non-dispatchable functions” is one I just made up, as far as I’m aware, because it makes sense in this context. The motivation of future-compatibility is just my guess, too.

I might want to read up some actual sources around relevant RFCs and/or PRs, for precise (intended) behavior, terminology, and motivation of the behavior of self: Self but not Self: Sized methods in traits.

For review, especially if any of my “guesses” here are wrong, I’d thus also appreciate relevant links to relevant discussions to learn from.

@steffahn
Copy link
Member Author

cc @QuineDot since you recently opened #1445, so you might have some ideas or feedback here

@steffahn steffahn changed the title Document how Self receiver types *actually* interact with object safety Document how self: Self receiver types *actually* interact with object safety Jan 26, 2024
@QuineDot
Copy link

QuineDot commented Jun 5, 2024

See this PR -- it's not just Self: Sized that makes a method non-dispatchable, it's TypeInvolvingSelf: NonAutoTrait... plus some others. See also.

I haven't experimented enough to feel 💯 confident in what is and isn't accepted, and there is some wonkiness around the check. Such as the "empty bounds" in the examples below...

Example where clauses which are fine (do not make the method non-dispatchable):

  • Self: Send
  • Self: 'a
  • Self:
  • Self::AssociatedType: Debug
  • Box<Self>: 'a

Example where clauses which make the method non-dispatchable:

  • Self: Debug
  • Box<Self>: Debug
  • Box<Self>: Send
  • Box<Self>: 🤷
  • dyn Trait<Assoc = Box<Self>>: Debug

Tangential aside: Self: Sized in an implied bound (e.g. where Self: Clone) also counts as explicitly non-dispatchable.

@traviscross
Copy link
Contributor

We reviewed this PR in the rustdocs call, and we've asked for review of this by the types team in:

Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

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

One idea, this otherwise looks fine to me

@@ -81,13 +82,26 @@ Object safe traits can be the base trait of a [trait object]. A trait is
* [`Box<Self>`]
* [`Rc<Self>`]
* [`Arc<Self>`]
* [`Pin<P>`] where `P` is one of the types above
* [`Pin<P>`] where `P` is one of the types in this list (this also applies recursively)
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we could split this out to a "A type is a dispatchable receiver if it's one of: "

then we can say Pin<P> if P is a dispatchable receiver

Co-authored-by: Michael Goulet <michael@errs.io>
@@ -71,7 +71,8 @@ Object safe traits can be the base trait of a [trait object]. A trait is
* `Sized` must not be a [supertrait][supertraits]. In other words, it must not require `Self: Sized`.
* It must not have any associated constants.
* It must not have any associated types with generics.
* All associated functions must either be dispatchable from a trait object or be explicitly non-dispatchable:
* All associated functions must either be dispatchable from a trait object,
or be explicitly or implicitly non-dispatchable.
Copy link
Contributor

Choose a reason for hiding this comment

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

that terminology feels weird, fn foo<T> is also "implicitly non-dispatchable", isn't it?

All associated functions must either be dispatchable from a trait object or must not be applicable to trait objects

Suggested change
or be explicitly or implicitly non-dispatchable.
or must not be applicable to trait objects.

Comment on lines +90 to +94
* Explicitly non-dispatchable functions must:
* Have a `where Self: Sized` bound.
* Implicitly non-dispatchable functions must:
* Have the receiver type `Self` (i.e. `self`)
* Fulfill all the conditions of dispatchable functions, except for the receiver type.
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
* Explicitly non-dispatchable functions must:
* Have a `where Self: Sized` bound.
* Implicitly non-dispatchable functions must:
* Have the receiver type `Self` (i.e. `self`)
* Fulfill all the conditions of dispatchable functions, except for the receiver type.
* Non-applicable functions have either:
* a `where Self: Sized` bound.
* the receiver type `Self` (i.e. `self`) and fulfill all the conditions of dispatchable functions, except for the receiver type.

Comment on lines +96 to +98
Methods with `Self` receiver type are implicitly non-dispatchable
(“non-dispatchable” means that they cannot be called on trait object types), but
[might become dispatchable in future versions of Rust](https://github.com/rust-lang/rust/issues/48055).
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
Methods with `Self` receiver type are implicitly non-dispatchable
(non-dispatchable means that they cannot be called on trait object types), but
[might become dispatchable in future versions of Rust](https://github.com/rust-lang/rust/issues/48055).
Methods with `Self` receiver type are currently non-dispatchable
("non-dispatchable" means that they cannot be called on trait object types), but
[might become dispatchable in future versions of Rust](https://github.com/rust-lang/rust/issues/48055).

@traviscross traviscross added the S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author. label Jul 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rule around non-dispatchable functions doesn't match the compiler behavior
5 participants