diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 8af14d3c698..823e56b64e3 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -380,7 +380,13 @@ impl str { reason = "return type may change to be an iterator", issue = "27791")] pub fn escape_debug(&self) -> String { - self.chars().enumerate().flat_map(|(i, c)| c.escape_debug_ext(i == 0)).collect() + let mut string = String::with_capacity(self.len()); + let mut chars = self.chars(); + if let Some(first) = chars.next() { + string.extend(first.escape_debug_ext(true)) + } + string.extend(chars.flat_map(|c| c.escape_debug_ext(false))); + string } /// Escapes each char in `s` with [`char::escape_default`]. diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index 84c97abcbc2..d11bf5dc3e9 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -989,6 +989,12 @@ fn test_escape_unicode() { #[test] fn test_escape_debug() { + // Note that there are subtleties with the number of backslashes + // on the left- and right-hand sides. In particular, Unicode code points + // are usually escaped with two backslashes on the right-hand side, as + // they are escaped. However, when the character is unescaped (e.g. for + // printable characters), only a single backslash appears (as the character + // itself appears in the debug string). assert_eq!("abc".escape_debug(), "abc"); assert_eq!("a c".escape_debug(), "a c"); assert_eq!("éèê".escape_debug(), "éèê"); diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py index 1da5878c4c6..07f873b13c0 100755 --- a/src/libcore/unicode/unicode.py +++ b/src/libcore/unicode/unicode.py @@ -21,7 +21,7 @@ # - UnicodeData.txt # # Since this should not require frequent updates, we just store this -# out-of-line and check the unicode.py file into git. +# out-of-line and check the tables.rs file into git. import fileinput, re, os, sys, operator, math, datetime