# \`is\_...\` functions on char should have a unifed API

**URL:** <https://internals.rust-lang.org/t/is-functions-on-char-should-have-a-unifed-api/23584>\
**Category:** libs\
**Created:** [October 1, 2025, 5:00am UTC](https://internals.rust-lang.org/t/is-functions-on-char-should-have-a-unifed-api/23584 "2025-10-01T05:00:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ljtpetersen](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ljtpetersen/32/13666_2.png) [@ljtpetersen](https://internals.rust-lang.org/u/ljtpetersen)\
**Post date:** [October 1, 2025, 5:00am UTC](https://internals.rust-lang.org/t/is-functions-on-char-should-have-a-unifed-api/23584/1 "2025-10-01T05:00:53Z")

</div>

Here are two functions on `char`:

```rust
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`.

---

<div class="post-metadata">

**Author:** ![philomathic\_life](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/philomathic_life/32/13613_2.png) [@philomathic\_life](https://internals.rust-lang.org/u/philomathic_life)\
**Post date:** [October 1, 2025, 6:05am UTC](https://internals.rust-lang.org/t/is-functions-on-char-should-have-a-unifed-api/23584/2 "2025-10-01T06:05:34Z")

</div>

That would be a breaking change, and I believe this "inconsistency" was known when [`AsciiExt`](https://doc.rust-lang.org/std/ascii/trait.AsciiExt.html) 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))`).

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [October 1, 2025, 11:52am UTC](https://internals.rust-lang.org/t/is-functions-on-char-should-have-a-unifed-api/23584/3 "2025-10-01T11:52:43Z")

</div>

> [@philomathic\_life](#):
>
> That would be a breaking change

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

```rust
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?

---

<div class="post-metadata">

**Author:** ![programmerjake](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/programmerjake/32/5893_2.png) [@programmerjake](https://internals.rust-lang.org/u/programmerjake)\
**Post date:** [October 1, 2025, 12:06pm UTC](https://internals.rust-lang.org/t/is-functions-on-char-should-have-a-unifed-api/23584/4 "2025-10-01T12:06:42Z")

</div>

> [@toc](#):
>
> I think adding
> 
> ```rust
> impl<F> Pattern for F
> where
> F: FnMut(&char) -> bool, { ... }
> 
> ```
> 
> would be fine.

that doesn't work since a type can implement both `FnMut(char) -> bool` and `FnMut(&char) -> bool` so those conflict: [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=75d5ba452745d504ecf3663e8012c9c9)

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jrose/32/9591_2.png) [@jrose](https://internals.rust-lang.org/u/jrose)\
**Post date:** [October 2, 2025, 3:45am UTC](https://internals.rust-lang.org/t/is-functions-on-char-should-have-a-unifed-api/23584/5 "2025-10-02T03:45:50Z")

</div>

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. 🤷)
