Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
matthiaskrgr opened this issue Aug 14, 2018 · 4 comments
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints

Comments

@matthiaskrgr
Copy link
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
@csmoe csmoe added the A-diagnostics Area: Messages for errors, warnings, and lints label Aug 14, 2018
@matthew-russo
Copy link
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
Copy link
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
Copy link
Member Author

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.

frewsxcv added a commit to frewsxcv/rust that referenced this issue Aug 17, 2018
…haelwoerister

Do not suggest conversion method that is already there

Fix rust-lang#53348.
@ishowta
Copy link

ishowta commented Oct 1, 2020

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
Labels
A-diagnostics Area: Messages for errors, warnings, and lints
Projects
None yet
Development

No branches or pull requests

4 participants