Skip to content

Commit 180b4ce

Browse files
committed
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 rust-lang#13567
1 parent d03c1c8 commit 180b4ce

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

crates/syntax/src/ast/token_ext.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,17 +209,19 @@ impl ast::String {
209209
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
210210

211211
let mut buf = String::new();
212-
let mut text_iter = text.chars();
212+
let mut prev = 0;
213213
let mut has_error = false;
214214
unescape_literal(text, Mode::Str, &mut |char_range, unescaped_char| match (
215215
unescaped_char,
216216
buf.capacity() == 0,
217217
) {
218218
(Ok(c), false) => buf.push(c),
219-
(Ok(c), true) if char_range.len() == 1 && Some(c) == text_iter.next() => (),
219+
(Ok(_), true) if char_range.len() == 1 && char_range.start == prev => {
220+
prev = char_range.end
221+
}
220222
(Ok(c), true) => {
221223
buf.reserve_exact(text.len());
222-
buf.push_str(&text[..char_range.start]);
224+
buf.push_str(&text[..prev]);
223225
buf.push(c);
224226
}
225227
(Err(_), _) => has_error = true,
@@ -252,17 +254,19 @@ impl ast::ByteString {
252254
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
253255

254256
let mut buf: Vec<u8> = Vec::new();
255-
let mut text_iter = text.chars();
257+
let mut prev = 0;
256258
let mut has_error = false;
257259
unescape_literal(text, Mode::ByteStr, &mut |char_range, unescaped_char| match (
258260
unescaped_char,
259261
buf.capacity() == 0,
260262
) {
261263
(Ok(c), false) => buf.push(c as u8),
262-
(Ok(c), true) if char_range.len() == 1 && Some(c) == text_iter.next() => (),
264+
(Ok(_), true) if char_range.len() == 1 && char_range.start == prev => {
265+
prev = char_range.end
266+
}
263267
(Ok(c), true) => {
264268
buf.reserve_exact(text.len());
265-
buf.extend_from_slice(text[..char_range.start].as_bytes());
269+
buf.extend_from_slice(text[..prev].as_bytes());
266270
buf.push(c as u8);
267271
}
268272
(Err(_), _) => has_error = true,
@@ -445,6 +449,12 @@ mod tests {
445449
check_string_value(r"\foobar", None);
446450
check_string_value(r"\nfoobar", "\nfoobar");
447451
check_string_value(r"C:\\Windows\\System32\\", "C:\\Windows\\System32\\");
452+
check_string_value(r"\x61bcde", "a\x62cde");
453+
check_string_value(
454+
r"a\
455+
bcde", "a\
456+
bcde",
457+
);
448458
}
449459

450460
#[test]

0 commit comments

Comments
 (0)