-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Trait object coercion supercedes deref coercion #39801
Comments
@nikomatsakis @nrc Wasn't sure who to ping here, just looking for a judgement on whether this behavior is intended or if it's something that can be improved. |
@abonander hmm yes I agree this is suboptimal. I'm not sure what fix, if any, to do though. For one thing, if we made changes here, it might break code that is using the existing behavior -- and it seems like we'd be trying to make a very narrow targeted change here? (i.e., to detect the case where the trait object would be the same as the result of the deref). cc @rust-lang/lang |
@nikomatsakis We could try to just reverse the order, I believe both fall through if they fail. |
Well the problem that I have isn't that trait object coercion supersedes deref coercion, it's that the compiler doesn't try deref coercion when trait object coercion fails. If we got that working, then it wouldn't break anything, it would just make more code compile that didn't before. |
@abonander It's tricky, because it fails later, and that's required so it doesn't fail if more inference is required, although we could compromise a bit more here? Still, I'm not too happy about more hacks. |
Reversing the order I think would introduce subtle breakage because if you have |
Yeah I'm wary of trying to change the order because of breakage. |
I was wondering if any further progress had been made on this? I'm encountering several examples of this defect in code i've been constructing that is using custom smart pointers, and the added derefs are clunky and unhelpful. |
I'm still thinking the compiler should attempt both coercions before erroring. |
In addition to the above example, methods can normally be called by passing self as an argument, but not in this case where a trait object would require deref coercion:
This seems like an ergonomics consistency issue/bug. |
Here's the same issue, this time passing a boxed Bar to a generic parameter which implements Foo:
|
I think these inconsistencies are confusing, especially for new users, and especially in the example of Box<T> which otherwise acts pretty much like T. |
I guess this is the expected behaviour? Check RFC401
It's more like a diagnostic issue to me. |
Is this the same issue? It seems related, but slightly different since in this case the trait is generic, rather than the function? struct MyType;
impl From<&[u8]> for MyType {
fn from(_: &[u8]) -> Self {
Self
}
}
fn takes_slice(_: &[u8]) {}
fn main() {
takes_slice(b"");
let _ = MyType::from(b""); //~ ERROR the trait bound `MyType: From<&[u8; 0]>` is not satisfied
} At least in this case, there is a nice diagnostic Still, this feels a bit unexpected since |
This seems like it should work: Playground link
However, it seems the compiler is attempting to coerce
&Arc<Foo>
to a trait object before attempting deref coercion, which gives this unintuitive error:Adding a deref-reref seems to fix the issue, but it's definitely a papercut:
The text was updated successfully, but these errors were encountered: