String type coercion in rust


#1

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?


#2

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 https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md (CTRL-F for “matching traits”).


#3

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:


#4

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.


#5

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.


#6

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.


#7

This is now mentioned in the (nightly) book: http://doc.rust-lang.org/nightly/book/strings.html