Skip to content

Rule around non-dispatchable functions doesn't match the compiler behavior #1247

Description

@upsuper

In the Object Safety section, it says:

  • Explicitly non-dispatchable functions require:
    • Have a where Self: Sized bound (receiver type of Self (i.e. self) implies this).

This implies that if you have any associated function with receiver of self should be counted as non-dispatchable function. However, it is not the case. See the following code:

trait Foo {
    fn a(self);
    // fn b(self, x: &Self);
    // fn c(self) -> Self;
}

fn test() -> Box<dyn Foo> { todo!() }

Uncommenting b or c would make the code fail to compile, unless explicit where Self: Sized is added, but the rule in the reference indicates that having a receiver self already implies that bound exists.

Not sure whether it's something that should be fixed in the reference or the compiler.

Activity

  1. bjorn3 commented on Aug 12, 2022

    @bjorn3
    Member

    a is actually dispatchable when the unstable #![feature(unsized_fn_params)] is enabled.

  2. upsuper commented on Aug 12, 2022

    @upsuper
    ContributorAuthor

    Sounds like the reference should remove "receiver type of Self (i.e. self) implies this", and possibly mention that while self in receiver doesn't violate object safety, unsized_fn_params is required to actually use it as dispatchable.

  3. Havvy commented on Aug 14, 2022

    @Havvy
    Contributor

    Okay, looking into this way too long, I think I understand what the original author meant by the parenthetical. Specifically, having a bound of Self: Sized is implied by having the receiver be self because it is a requirement that the programmer specify that Self: Sized on the method or it won't compile.

    I don't like parentheticals at all and would rather it be a note using the note notation explaining it similarly to how I just wrote it. Though not exactly; the word "implied" should not be used at all since it is confusing as evidence by this issue.

    We also have a policy of discussing Rust as it currently exists. We don't talk about unstable features. So any fix for this issue should not mention them.

  4. added
    Language CleanupImprovements to existing language which is correct but not clear, or missing examples, or the like.
    on Aug 14, 2022
  5. upsuper commented on Aug 14, 2022

    @upsuper
    ContributorAuthor

    Specifically, having a bound of Self: Sized is implied by having the receiver be self because it is a requirement that the programmer specify that Self: Sized on the method or it won't compile.

    However, this is not true. As the example shows, fn a(self); compiles totally fine in stable Rust, so the logic is more consistent if we understand it as a dispatchable rather than a (implied or not) non-dispatchable.

  6. Havvy commented on Aug 14, 2022

    @Havvy
    Contributor

    Oh, yeah. I tried fn a(self) {} and that failed asking to add the Sized bound. And I can even create a value of Box<dyn Foo> but I get errors if I try to call a on it. So yeah, the entire parenthetical can just be removed then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-typesArea: TypesLanguage CleanupImprovements to existing language which is correct but not clear, or missing examples, or the like.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions