/// 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 {
pub fn is_fatal(&self) -> bool {
match self {
EscapeError::UnskippedWhitespaceWarning => false,
+ EscapeError::MultipleSkippedLinesWarning => false,
_ => true,
}
}
.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
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",
&[
(6..7, Ok('x')),
],
);
+ check("\\\n \n x", &[(0..7, Err(EscapeError::MultipleSkippedLinesWarning)), (7..8, Ok('x'))]);
}
#[test]
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();
+ }
}
}