Skip to content

to_ascii_uppercase and to_ascii_lowercase operate on non-ASCII characters #31203

Closed

Description

@DanielKeep

Behold!

#[test]
fn liar_liar_pants_on_fire() {
    use std::ascii::AsciiExt;
    assert_eq!("café".to_ascii_uppercase(), "CAFÉ");
    assert_eq!("café".to_ascii_uppercase(), "CAFé");
    assert_eq!("CAFÉ".to_ascii_lowercase(), "café");
    assert_eq!("CAFÉ".to_ascii_lowercase(), "cafÉ");
}

This is obviously silly. The problem is that this is running an ASCII-only operation on Unicode strings without actually dealing with their Unicode-ness.

These functions should either correctly deal with grapheme clusters (by ignoring them since they're not in ASCII), or document that it does not correctly handle grapheme clusters, preferably with an example (like the above).

(Actually having a standard Ascii type would be even more muchly preferable, but I suspect that's way out of scope.)

Activity

  1. steveklabnik commented on Jan 26, 2016

    @steveklabnik
    Contributor
  2. frewsxcv commented on Jan 26, 2016

    @frewsxcv
    Contributor

    In case anyone is curious why this works: café is actually represented cafe\u{301}

    https://en.wikipedia.org/wiki/Combining_character

  3. tbu- commented on Jan 27, 2016

    @tbu-
    Contributor

    @steveklabnik It would be nice if the documentation could mention that it operates on codepoints, not grapheme clusters.

  4. frewsxcv commented on Jan 27, 2016

    @frewsxcv
    Contributor

    Also, worth considering adding one of the examples above to go with it

  5. steveklabnik commented on Jan 27, 2016

    @steveklabnik
    Contributor

    @tbu- nothing in the standard library operates on grapheme clusters, though. I'm not sure what the right level of repeating this is.

    Maybe @frewsxcv is right here, and an example is the best way for this particular function.

  6. tbu- commented on Jan 27, 2016

    @tbu-
    Contributor

    I think it's confusing that it talks about characters when it exhibits the weird behaviour mentioned above. Maybe it could just explicitly codepoints?

  7. steveklabnik commented on Jan 27, 2016

    @steveklabnik
    Contributor

    char is a unicode scalar value. So 'character' is always referring to a codepoint, not a grapheme.

  8. tbu- commented on Jan 27, 2016

    @tbu-
    Contributor

    Yes, it's confusing naming unfortunately. Maybe we could add these unexpected test cases to the documentation?

  9. DanielKeep commented on Jan 28, 2016

    @DanielKeep
    ContributorAuthor

    For what it's worth, although I'd prefer this method do "the right thing", simply having an example to make the behaviour with respect to combining code points clear would be a reasonable solution.

  10. bluss commented on Jan 28, 2016

    @bluss
    Contributor

    @steveklabnik Note that this function may transform "é" to "É", which is the "ascii violating" behavior

    It needs pointing out in the doc. However, we don't need to mention grapheme clusters. It is application dependent which algorithms you use over your unicode data. Implying that grapheme clusters is always the right thing to do is misleading. Rust strings are brilliant as they are in providing minimal unicode consistency with low overhead.

  11. steveklabnik commented on Jan 28, 2016

    @steveklabnik
    Contributor

    Yes, I would also think that examples of this are a good idea.

  12. frewsxcv commented on Feb 4, 2016

    @frewsxcv
    Contributor

    I took a stab at this: #31401

  13. added a commit that references this issue on Feb 4, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions