Unnamed repository; edit this file 'description' to name the repository.
Fix the length displayed for byte string literals with escaped newlines
The length of byte strings containing escaped newlines is displayed two bytes longer when the first escaped character is a newline. This is due to a small bug in handling the first escaped newline in string literals. Closes #13567
Noritada Kobayashi 2022-11-07
parent d03c1c8 · commit 180b4ce
-rw-r--r--crates/syntax/src/ast/token_ext.rs22
1 files changed, 16 insertions, 6 deletions
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index ba72e64425..22ad6db9ae 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -209,17 +209,19 @@ impl ast::String {
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
let mut buf = String::new();
- let mut text_iter = text.chars();
+ let mut prev = 0;
let mut has_error = false;
unescape_literal(text, Mode::Str, &mut |char_range, unescaped_char| match (
unescaped_char,
buf.capacity() == 0,
) {
(Ok(c), false) => buf.push(c),
- (Ok(c), true) if char_range.len() == 1 && Some(c) == text_iter.next() => (),
+ (Ok(_), true) if char_range.len() == 1 && char_range.start == prev => {
+ prev = char_range.end
+ }
(Ok(c), true) => {
buf.reserve_exact(text.len());
- buf.push_str(&text[..char_range.start]);
+ buf.push_str(&text[..prev]);
buf.push(c);
}
(Err(_), _) => has_error = true,
@@ -252,17 +254,19 @@ impl ast::ByteString {
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
let mut buf: Vec<u8> = Vec::new();
- let mut text_iter = text.chars();
+ let mut prev = 0;
let mut has_error = false;
unescape_literal(text, Mode::ByteStr, &mut |char_range, unescaped_char| match (
unescaped_char,
buf.capacity() == 0,
) {
(Ok(c), false) => buf.push(c as u8),
- (Ok(c), true) if char_range.len() == 1 && Some(c) == text_iter.next() => (),
+ (Ok(_), true) if char_range.len() == 1 && char_range.start == prev => {
+ prev = char_range.end
+ }
(Ok(c), true) => {
buf.reserve_exact(text.len());
- buf.extend_from_slice(text[..char_range.start].as_bytes());
+ buf.extend_from_slice(text[..prev].as_bytes());
buf.push(c as u8);
}
(Err(_), _) => has_error = true,
@@ -445,6 +449,12 @@ mod tests {
check_string_value(r"\foobar", None);
check_string_value(r"\nfoobar", "\nfoobar");
check_string_value(r"C:\\Windows\\System32\\", "C:\\Windows\\System32\\");
+ check_string_value(r"\x61bcde", "a\x62cde");
+ check_string_value(
+ r"a\
+bcde", "a\
+bcde",
+ );
}
#[test]