-
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
Suggest dereference operations when a deref coercion won't work #39029
Comments
If you can find the deref well enough to put it in the error message, might as well fix the actual bug and apply the coercion. Maybe that needs an RFC. |
No, that's a language change, and leads to hidden changes in semantics as traits get implemented. It's not a clear win. The rfc explicitly calls this out (https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md, see "Note that we do not perform coercions when matching traits". This RFC doesn't actually talk of deref coercions which were introduced earlier, but the semantics are the same and the reasoning probably applies too) If we want this, we need to rfc it. |
For now, I added (still waiting for help from @nikomatsakis) ref suggestions, so I guess this is the next step. |
`ToSocketAddrs` is implemented for a number of different types, including `(IpAddr, u16)`, `&str`, and various others, for the convenience of being able to run things like `TcpListener::bind("10.11.12.13:1415")`. However, because this is a generic parameter with a trait bound, if you have a `String` you cannot pass it in, either directly as `TcpListener::bind(string)`, or the `TcpListener::bind(&string)` as you might expect due to deref coercion; you have to use `TcpListener::bind(&*string)`, which is noisy and hard to discover (though rust-lang#39029 suggests better error messages to make it more discoverable). Rather than making people stumble over this, just implement `ToSocketAddrs` for `String`.
…ichton impl ToSocketAddrs for String `ToSocketAddrs` is implemented for a number of different types, including `(IpAddr, u16)`, `&str`, and various others, for the convenience of being able to run things like `TcpListener::bind("10.11.12.13:1415")`. However, because this is a generic parameter with a trait bound, if you have a `String` you cannot pass it in, either directly as `TcpListener::bind(string)`, or the `TcpListener::bind(&string)` as you might expect due to deref coercion; you have to use `TcpListener::bind(&*string)`, which is noisy and hard to discover (though #39029 suggests better error messages to make it more discoverable). Rather than making people stumble over this, just implement `ToSocketAddrs` for `String`.
@Manishearth could you come up with a different repro case for this? I believe this was fixed in the meantime by making deref coercions work, but I'm not sure. If it has been fixed, then we can close this ticket. |
I don't think this has been fixed, but i don't have the bandwidth to figure this out |
Deref coercions are tricky.
&x
will coerce to&***x
if used in a place that expects a value of the type of&***x
, however, this does not work for trait-bound generics.The example that came up recently was:
This errors with
because while
&owned
would usually coerce to an&str
, in this case it doesn't because even thoughTcpListener::bind
would accept a&str
, it doesn't accept only that type and the deref coercion won't work.Programmers should not have to know these details to get their code to work. It would be nice if deref coercions worked in places where a generic bound type is expected, but there are other issues there (what happens if the trait gets implemented on
String
?) so it's not a clear win and would need an rfc anyway.At the very least, we should suggest the usage of a dereference operator here.
The heuristics are:
&x
&x
&***x
for some amount of*
operationsthen, suggest the correct thing with the dereference operators.
cc @jonathandturner @GuillaumeGomez
The text was updated successfully, but these errors were encountered: