d33tah
d33tah

Reputation: 11569

The trait `FnMut<(char,)>` is not implemented for `String` when trying to split a string

I need to split a String (not &str) by another String:

use std::str::Split;

fn main() {
    let x = "".to_string().split("".to_string());
}

Why do I get this error and how to avoid it if I already have to operate on strings?

error[E0277]: the trait bound `std::string::String: std::ops::FnMut<(char,)>` is not satisfied
 --> src/main.rs:4:32
  |
4 |         let x = "".to_string().split("".to_string());
  |                                ^^^^^ the trait `std::ops::FnMut<(char,)>` is not implemented for `std::string::String`
  |
  = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `std::string::String`

According to the #rust-beginners IRC channel, this might be an example of Deref failing in 1.20.0-nightly. How to split a string in Rust? doesn't address the problem of splitting by String, not &str.

Upvotes: 6

Views: 2596

Answers (2)

d33tah
d33tah

Reputation: 11569

I talked about this with #rust-beginners IRC channel and heard the following:

15:12:15           achird | d33tah: split accepts a Pattern, where Pattern can be &str or char, but you're passing a String (no idea why deref is not working)
15:13:01           d33tah | achird: thanks! how can I convert string to str?
15:13:03           achird | i think a simple split(&delimiter2) should fix the problem
15:16:26           calops | why isn't deref working though?
15:21:33        @mbrubeck | calops, d33tah: Deref coercions only work if one exact "expected" type is known.  For a generic type like <P: Pattern>, coercion doesn't kick in.
15:24:11        @mbrubeck | d33tah: The error should definitely be improved...  It should complain that `String` doesn't impl `Pattern`, instead of jumping straight to `FnMut(char)`

So basically, the solution is to add & before the delimiter string, like this:

fn main() {
    let s1 = "".to_string();
    let s2 = "".to_string();
    let x = s1.split(&s2);
}

Upvotes: 4

Boiethios
Boiethios

Reputation: 42829

All is in the documentation. You can provide one of:

  • A &str,
  • A char,
  • A closure,

Those three types implement the Pattern trait. You are giving a String to split instead of a &str.

Example:

fn main() {
    let x = "".to_string();
    let split = x.split("");
}

Upvotes: 6

Related Questions