Skip to content

diagnostics: "try using a conversion method: `*i.to_string().to_string()" #53348

Closed
@matthiaskrgr

Description

@matthiaskrgr
Member

Example I came up with (tried to reduce from a larger set of code I found this in)

fn main() {
	let mut v = vec!["hello", "this", "is", "a", "test"];

	let v2 = Vec::new();
	
	v.into_iter().map(|s|s.to_owned()).collect::<Vec<_>>();
	
	let mut a = String::new();
	for i in v {
		a = *i.to_string();
		v2.push(a);
	}
}

This gives a rather confusing error message:

error[E0308]: mismatched types
  --> src/main.rs:10:7
   |
10 |         a = *i.to_string();
   |             ^^^^^^^^^^^^^^
   |             |
   |             expected struct `std::string::String`, found str
   |             help: try using a conversion method: `*i.to_string().to_string()`
   |
   = note: expected type `std::string::String`
              found type `str`

meta:

rustc 1.30.0-nightly (d5a448b3f 2018-08-13)
binary: rustc
commit-hash: d5a448b3f47b22c9cb010198bdcc49d4392b090b
commit-date: 2018-08-13
host: x86_64-unknown-linux-gnu
release: 1.30.0-nightly
LLVM version: 7.0

Activity

added
A-diagnosticsArea: Messages for errors, warnings, and lints
on Aug 14, 2018
matthew-russo

matthew-russo commented on Aug 15, 2018

@matthew-russo
Contributor

Not sure if this is entirely correct but I'm pretty sure it has to do with precedence of the dereference.

This code has the same issue:

fn main() {
	let hello = String::from("hello");
	let mut vec: Vec<String> = Vec::new();
	vec.push(*hello.to_string());
}

while if you write:

fn main() {
	let hello = String::from("hello");
	let mut vec: Vec<String> = Vec::new();
	vec.push((*hello).to_string());
}

it will compile fine.

@matthiaskrgr Also just to note there were some other issues with the code you posted -- v2 was not mutable so couldn't be pushed to and the v.into_iter()... moved v so the for loop was then invalid due to moved value

matthew-russo

matthew-russo commented on Aug 15, 2018

@matthew-russo
Contributor

And also just wanted to point out that this is a redundant operation to begin with because you're trying to convert a String to a String.

fn main() {
	let v = vec!["hello", "this", "is", "a", "test"];

	let mut v2: Vec<String> = Vec::new();
	
	let owned = v.into_iter().map(|s|s.to_owned()).collect::<Vec<_>>();
	
	for i in owned {
		v2.push(i);
	}
}

This is an equivalent example with strong typing on v2 to see that its still Vec<String>.

or if you still wanted to iterate over v (ignoring the move) you could do:

fn main() {
	let v = vec!["hello", "this", "is", "a", "test"];

	let mut v2: Vec<String> = Vec::new();
	
	for i in v {
		v2.push(i.to_string());
	}
}
matthiaskrgr

matthiaskrgr commented on Aug 15, 2018

@matthiaskrgr
MemberAuthor

Yeah, I know the code is quite wonky, :) I was in the middle of a refactoring when I stumbled over the .to_string().to_string() oddity.

added a commit that references this issue on Aug 17, 2018

Rollup merge of rust-lang#53406 - estebank:to_string-to_string, r=mic…

4cdcb23
ishowta

ishowta commented on Oct 1, 2020

@ishowta

This problem looks essentially the same as #64919 and that has been resolved.
So I think #53406 should be reverted.
It's confusing if there are no hints.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @matthiaskrgr@ishowta@matthew-russo@csmoe

        Issue actions

          diagnostics: "try using a conversion method: `*i.to_string().to_string()" · Issue #53348 · rust-lang/rust