Skip to content

&[char;_]: doesn't implement Pattern while &[char] does #86329

Closed
@chorman0773

Description

@chorman0773

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions