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

Literal &[char] patterns clumsily require an as conversion #39511

Closed
jimblandy opened this issue Feb 3, 2017 · 5 comments · Fixed by #86336
Closed

Literal &[char] patterns clumsily require an as conversion #39511

jimblandy opened this issue Feb 3, 2017 · 5 comments · Fixed by #86336
Labels
C-enhancement Category: An issue proposing an enhancement or a PR with one. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@jimblandy
Copy link
Contributor

Many str methods accept patterns of any type that implements the std::str::pattern::Pattern trait. One such type is &[char], which matches any single character mentioned in the pattern slice.

However, &[char] patterns are not as nice to use as one might hope. This does not compile:

        let code = "\t    function noodle() { ";
        assert_eq!(code.trim_left_matches(&[' ', '\t']),
                   "function noodle() { ");

Rust complains:

error[E0277]: the trait bound `[char; 2]: std::ops::Fn<(char,)>` is not satisfied
   --> lib.rs:689:29
    |
689 |             assert_eq!(code.trim_left_matches(&[' ', '\t']),
    |                             ^^^^^^^^^^^^^^^^^ the trait `std::ops::Fn<(char,)>` is not implemented for `[char; 2]`
    |
    = note: required because of the requirements on the impl of `std::ops::FnOnce<(char,)>` for `&[char; 2]`
    = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&[char; 2]`

The trim_left_matches method constrains its argument type P with P: Pattern, and Rust won't apply the usual type coercions like &[T; N] to &[T] in order to satisfy trait bounds.

One must instead write:

            let code = "\t    function noodle() { ";
            assert_eq!(code.trim_left_matches(&[' ', '\t'] as &[char]),
                       "function noodle() { ");

It's not a tragedy, but it's not pretty either.

CC @alexcrichton

@petrochenkov
Copy link
Contributor

Shorter version: &[' ', '\t'][..]

@alexcrichton
Copy link
Member

cc @Kimundi

@jimblandy
Copy link
Contributor Author

jimblandy commented Feb 3, 2017

Shorter version: &[' ', '\t'][..]

Lovely! This hadn't occurred to me.

@Kimundi
Copy link
Member

Kimundi commented Mar 9, 2017

Yeah, this was a known issue from the start.

This concrete impl is basically a originally-nice API that is old enough that it got gradually worse over time in multiple iterations. If I remember right, there was originally a hardcoded method that just took a &[char], and the language still allowed array literals to coerce to static slices, so originally you could do foo(['a', 'x', '0']). At some point we got a cleaning up of the expression syntax, which lead to foo(&['a', 'x', '0']). And then when I proposed the Pattern trait the methods got generic, and no longer liked to do deref coercions, leading to the ugly foo(&['a', 'x', '0'][..]) as shortest possible literal form.

I think the only real "fix" for this is deprecating this pattern, and/or holding out till we have char array generics and can have a Pattern impl for all [char; N] directly.

@steveklabnik steveklabnik added A-libs T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Mar 9, 2017
@Mark-Simulacrum Mark-Simulacrum added T-lang Relevant to the language team, which will review and decide on the PR/issue. and removed T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jun 19, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 27, 2017
@steveklabnik
Copy link
Member

Triage:

I think the only real "fix" for this is deprecating this pattern, and/or holding out till we have char array generics and can have a Pattern impl for all [char; N] directly.

Seems like the same status today; we are making progress on const generics, but it's not ready yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: An issue proposing an enhancement or a PR with one. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants