Skip to content

Suggest dereference operations when a deref coercion won't work #39029

Closed
@Manishearth

Description

@Manishearth

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:

use std::net::TcpListener;
let owned = "foobar".to_string(); // owned string came from somewhere
let works = TcpListener::bind("some string");
let doesn't = TcpListener::bind(&owned);

This errors with

error[E0277]: the trait bound `std::string::String: std::net::ToSocketAddrs` is not satisfied
 --> <anon>:5:18
  |
5 |     let listen = TcpListener::bind(&owned);
  |                  ^^^^^^^^^^^^^^^^^ the trait `std::net::ToSocketAddrs` is not implemented for `std::string::String`
  |
  = note: required because of the requirements on the impl of `std::net::ToSocketAddrs` for `&std::string::String`
  = note: required by `std::net::TcpListener::bind`

because while &owned would usually coerce to an &str, in this case it doesn't because even though TcpListener::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:

  • you have a trait bound error
  • The error is on a reference expression &x
  • The expression is used in one of the allowed places for deref coercions (may not be necessary, really)
  • The trait isn't implemented by &x
  • The trait is implemented by &***x for some amount of * operations

then, suggest the correct thing with the dereference operators.

cc @jonathandturner @GuillaumeGomez

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions