Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Warn when an escaped newline skips multiple lines
  • Loading branch information
jesyspa committed Aug 11, 2021
commit a03fbfe2ff3e7dd03af42d337b11552e782e2dc4
9 changes: 9 additions & 0 deletions compiler/rustc_lexer/src/unescape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,17 @@ pub enum EscapeError {
/// After a line ending with '\', the next line contains whitespace
/// characters that are not skipped.
UnskippedWhitespaceWarning,

/// After a line ending with '\', multiple lines are skipped.
MultipleSkippedLinesWarning,
}

impl EscapeError {
/// Returns true for actual errors, as opposed to warnings.
pub fn is_fatal(&self) -> bool {
match self {
EscapeError::UnskippedWhitespaceWarning => false,
EscapeError::MultipleSkippedLinesWarning => false,
_ => true,
}
}
Expand Down Expand Up @@ -320,6 +324,11 @@ where
.bytes()
.position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r')
.unwrap_or(str.len());
if str[1..first_non_space].contains('\n') {
// The +1 accounts for the escaping slash.
let end = start + first_non_space + 1;
callback(start..end, Err(EscapeError::MultipleSkippedLinesWarning));
}
let tail = &str[first_non_space..];
if let Some(c) = tail.chars().nth(0) {
// For error reporting, we would like the span to contain the character that was not
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_lexer/src/unescape/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ fn test_unescape_str_warn() {
assert_eq!(unescaped, expected);
}

// Check we can handle escaped newlines at the end of a file.
check("\\\n", &[]);
check("\\\n ", &[]);

check(
"\\\n \u{a0} x",
&[
Expand All @@ -115,6 +119,7 @@ fn test_unescape_str_warn() {
(6..7, Ok('x')),
],
);
check("\\\n \n x", &[(0..7, Err(EscapeError::MultipleSkippedLinesWarning)), (7..8, Ok('x'))]);
}

#[test]
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ pub(crate) fn emit_unescape_error(
format!("non-ASCII whitespace symbol '{}' is not skipped", c.escape_unicode());
handler.struct_span_warn(span, &msg).span_label(char_span, &msg).emit();
}
EscapeError::MultipleSkippedLinesWarning => {
let msg = "multiple lines skipped by escaped newline";
let bottom_msg = "skipping everything up to and including this point";
handler.struct_span_warn(span, msg).span_label(span, bottom_msg).emit();
}
}
}

Expand Down