Description
I tried this code:
fn main(){
println!("{}","foo:bar".split(&[':']).collect::<Vec<_>>())
}
I expected to see this happen: Outputs ["foo","bar"]
Instead, this happened (playground output: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018):
rror[E0277]: expected a `Fn<(char,)>` closure, found `[char; 1]`
--> src/main.rs:1:44
|
1 | fn main(){println!("{:?}",{"foo:bar".split(&[':']).collect::<Vec<_>>()});}
| ^^^^^^ expected an `Fn<(char,)>` closure, found `[char; 1]`
|
= help: the trait `Fn<(char,)>` is not implemented for `[char; 1]`
= note: required because of the requirements on the impl of `FnOnce<(char,)>` for `&[char; 1]`
= note: required because of the requirements on the impl of `Pattern<'_>` for `&[char; 1]`
error[E0599]: the method `collect` exists for struct `std::str::Split<'_, &[char; 1]>`, but its trait bounds were not satisfied
--> src/main.rs:1:52
|
1 | fn main(){println!("{:?}",{"foo:bar".split(&[':']).collect::<Vec<_>>()});}
| ^^^^^^^ method cannot be called on `std::str::Split<'_, &[char; 1]>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`&[char; 1]: Pattern<'_>`
which is required by `std::str::Split<'_, &[char; 1]>: Iterator`
`std::str::Split<'_, &[char; 1]>: Iterator`
which is required by `&mut std::str::Split<'_, &[char; 1]>: Iterator`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
Meta
rustc --version --verbose
:
rustc 1.55.0 nightly (2021.06.14)
No backtrace for diagnostic
Further Information
There are two issues here, for one, the diagnostic is somewhat confusing. I expect that an array is not a closure, but I would expect it to be a pattern (Thus, telling me it isn't a closure isn't helpful to me). The second is the actual issue that references to arrays aren't Patterns.
According to the .split
docs, it's valid to pass a slice of char
to split
as the pattern. It should follow that you can pass a reference to an array to .split
, because references to arrays coerce to references to slices.
Both issues could be fixed with impl<const N: usize> Pattern for &[char;N]{...}
in the stdlib. It may also be useful (and was brought up in discussion on the Rust Community Discord), for a non-reference impl impl<const N: usize> Pattern for [char;N]{...}
. In the former case, it should be achievable by delegating to the slice impl. I am unfamiliar with the implementation in particular, but the same may also be reasonable for the by-value array case.