Skip to content

Compiler help: &str -> String suggestion about to_string #77575

@darnuria

Description

@darnuria

Note: If the discussion I suggest settle to a consensus for change I would be happy to be mentored to make a change!

I open this issue in mind that a similar issue #40762 was closed in Apr 25, 2017 but the situation has changed and also in my mind due to the state of the Rust book (details about search below).

Situation

I teach Rust to bachelors 2 students in computer science and and a Rustlings an exercise about strings involve understanding usage of String and &str, one possible outcome is to give a &str instead of a String like in this code:

fn print_with_string(s: String) {
    println!("{}", s);    
}

fn main() {
    let s = "Hello";
    print_with_string(s);
}

This result in this compiler message in rust stable:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
 --> src/main.rs:6:23
  |
6 |     print_with_string(c)
  |                       ^
  |                       |
  |                       expected struct `std::string::String`, found `&str`
  |                       help: try using a conversion method: `c.to_string()`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

Same almost the same message in nightly.

🔎 Actual state about this in the book

Edit: Promoted this section upper in discussion to provide reference quickly.

Learning difficulty

Pointing about to_string() introduce some complexity since the new standard in book is String::from(c).

I now that a looot of historical way to convert to String exist.

List thanks to internal forum member @jethrogb:

  • "hello".to_owned()
  • "hello".to_string()
  • String::from("hello")
  • "hello".into()
  • format!("hello") maybe not exactly intended for but some of my student used it in exercise I was surprised.

I found that as Rust is a difficult language (to teach/and learn), using a conventionalized way of converting remove some burden on student (also on reading), as they learn since they can get a grasp by following teaching material.

In teacher perspective explaining to learners "Okay! c.to_string() is exactly the same as String::from it's due to historical details" is not really the best experience. Bonus it hide the fact that a standardized way of converting now exist.

Actual implementation

Following @scottmcm and @estebank contribution to the discussion I added this section about what is the state in sources.
link /src/alloc/string.rs.html#2257-2262:

#[stable(feature = "str_to_string_specialization", since = "1.9.0")]
impl ToString for str {
    #[inline]
    fn to_string(&self) -> String {
        String::from(self)
    }
}

Link [src/alloc/string.rs.html#2305-2311](<https://doc.rust-lang.org/src/alloc/string.rs.html#2305-2311):

#[stable(feature = "rust1", since = "1.0.0")]
impl From<&str> for String {
    #[inline]
    fn from(s: &str) -> String {
        s.to_owned()
    }
}

Purposed solution

I would be in favor suggesting usage of String::from, bonus it's give exposure to std::convert::From trait.

Backlog: this question seems like a real deal in learning experience and among intermediate Rustacean: https://users.rust-lang.org/t/what-is-the-idiomatic-way-to-convert-str-to-string/12160/11

Thanks for reading feel free to close if it's still not a major issue! 🎉
Edit: Fix code example.
Edit2: Improve readability by moving book link closer to the begging; add implementation links.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions