reference
reference copied to clipboard
Rule around non-dispatchable functions doesn't match the compiler behavior
In the Object Safety section, it says:
- Explicitly non-dispatchable functions require:
- Have a
where Self: Sizedbound (receiver type ofSelf(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.
a is actually dispatchable when the unstable #![feature(unsized_fn_params)] is enabled.
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.
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.
Specifically, having a bound of
Self: Sizedis implied by having the receiver beselfbecause it is a requirement that the programmer specify thatSelf: Sizedon 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.
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.