String type coercion in rust

Hi everyone,

I've tried to make a simple app in rust with hyper library.

Here is the oneliner to start http server from the readme:

fn main() {
    Server::http(hello).listen("127.0.0.1:3000").unwrap();
}

I decided to add a bit more logging:

fn main() {
    let port = 3000;
    let host = format!("127.0.0.1:{}", port);
   Server::http(hello).listen(&host).unwrap();
   println!("Listening port {} on 127.0.0.1", port);
}

What I get is the error from the compiler about incompatible types:

src/main.rs:19:25: 19:38 error: the trait `std::net::addr::ToSocketAddrs` is not implemented for the type `collections::string::String` [E0277]
src/main.rs:19     Server::http(hello).listen(&host).unwrap();
                                       ^~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `id`.

The facts I know:

  • String should coerce to &str with &
  • The trait ToSocketAddrs is implemented for &str

So I really expected that coercion should happen here, and I'm not sure what needs to be done to fix compile error.

Could anyone point me to the right direction?

Auto deref coercion doesn't happen when traits need to be matched (per RFC 401, IIRC). You'll need to explicitly deref, e.g., &*host.

Found relevant section in rfcs/0401-coercions.md at master · rust-lang/rfcs · GitHub (CTRL-F for "matching traits").

4 Likes

I had exactly the same confusion using the postgres library the other day. Once I figured out I needed to be explicit I wound up using .borrow(). I'd go so far as to suggest the book needs a sentence of warning where it says "Strings will coerce into &str with an &" to point out that coercion is not the same as a cast. Is it just me (and @can3p)? :smile:

1 Like

This isn’t really answering the question but ToSocketAddrs is also implemented for (&str, u16), so you probably don’t need format! in the first place.

2 Likes

I brought this up a while ago, there are some reasons for not including it discussed in Pre-RFC: Auto-dereferencing parameters passed to generic functions as well as concrete ones.

This has hung me up several times recently (though I'm not processing Unicode, so it usually bytes me in the Vec<u8> / &[u8] relation). I was pretty sure that this feature had been removed since the book was updated. :smile: Thanks for the clarification and the RFC pointer.

Definitely think this deserves at least a footnote in the book. I also read through the language reference but don't see any mention of this.

1 Like

This is now mentioned in the (nightly) book: Strings

1 Like