`is_...` functions on char should have a unifed API

Here are two functions on char:

pub const fn is_whitespace(self) -> bool { /* ... */ }
pub const fn is_ascii(&self) -> bool { /* ... */ }

These have essentially the same signature. However, "abc".find(char::is_whitespace) compiles, wherease "abc".find(char::is_ascii) does not. This is because Pattern is implemented for FnMut(char) -> bool, but not FnMut(&char) -> bool.

For this reason, I believe that it should be ensured all similar functions on char have the same signature, such that they implement FnMut(char) -> bool.

4 Likes

That would be a breaking change, and I believe this "inconsistency" was known when AsciiExt was deprecated in favor for inherent methods with the same signature. You just have to live with making a closure instead (e.g., "abc".find(|c: char| c.is_ascii())/"abc".find(|c| char::is_ascii(&c))).

3 Likes

Changing the function signature would, but that is not the request. I think adding

impl<F> Pattern for F
where
    F: FnMut(&char) -> bool, { ... }

would be fine. Possibly impl Pattern for &char too while it's open. Is there a problem with adding those?

1 Like

that doesn't work since a type can implement both FnMut(char) -> bool and FnMut(&char) -> bool so those conflict: Rust Playground

1 Like

I suspect this is not a good idea, but Borrow<char> covers exactly this situation…

(Why do I suspect it’s not a good idea? At the very least, it probably makes it harder / worsens diagnostics when passing a closure expression instead of an existing function. :person_shrugging:)

2 Likes