diff options
Diffstat (limited to 'compiler/rustc_lexer/src/lib.rs')
| -rw-r--r-- | compiler/rustc_lexer/src/lib.rs | 85 |
1 files changed, 46 insertions, 39 deletions
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index e80196ed567..f6790f7ed1e 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -331,24 +331,37 @@ pub fn is_whitespace(c: char) -> bool { matches!( c, - // Usual ASCII suspects - '\u{0009}' // \t - | '\u{000A}' // \n + // End-of-line characters + | '\u{000A}' // line feed (\n) | '\u{000B}' // vertical tab | '\u{000C}' // form feed - | '\u{000D}' // \r - | '\u{0020}' // space - - // NEXT LINE from latin1 - | '\u{0085}' + | '\u{000D}' // carriage return (\r) + | '\u{0085}' // next line (from latin1) + | '\u{2028}' // LINE SEPARATOR + | '\u{2029}' // PARAGRAPH SEPARATOR - // Bidi markers + // `Default_Ignorable_Code_Point` characters | '\u{200E}' // LEFT-TO-RIGHT MARK | '\u{200F}' // RIGHT-TO-LEFT MARK - // Dedicated whitespace characters from Unicode - | '\u{2028}' // LINE SEPARATOR - | '\u{2029}' // PARAGRAPH SEPARATOR + // Horizontal space characters + | '\u{0009}' // tab (\t) + | '\u{0020}' // space + ) +} + +/// True if `c` is considered horizontal whitespace according to Rust language definition. +pub fn is_horizontal_whitespace(c: char) -> bool { + // This is Pattern_White_Space. + // + // Note that this set is stable (ie, it doesn't change with different + // Unicode versions), so it's ok to just hard-code the values. + + matches!( + c, + // Horizontal space characters + '\u{0009}' // tab (\t) + | '\u{0020}' // space ) } @@ -538,40 +551,32 @@ impl Cursor<'_> { debug_assert!(length_opening >= 3); // whitespace between the opening and the infostring. - self.eat_while(|ch| ch != '\n' && is_whitespace(ch)); + self.eat_while(|ch| ch != '\n' && is_horizontal_whitespace(ch)); - // copied from `eat_identifier`, but allows `.` in infostring to allow something like + // copied from `eat_identifier`, but allows `-` and `.` in infostring to allow something like // `---Cargo.toml` as a valid opener if is_id_start(self.first()) { self.bump(); - self.eat_while(|c| is_id_continue(c) || c == '.'); + self.eat_while(|c| is_id_continue(c) || c == '-' || c == '.'); } - self.eat_while(|ch| ch != '\n' && is_whitespace(ch)); + self.eat_while(|ch| ch != '\n' && is_horizontal_whitespace(ch)); let invalid_infostring = self.first() != '\n'; - let mut s = self.as_str(); let mut found = false; - let mut size = 0; - while let Some(closing) = s.find(&"-".repeat(length_opening as usize)) { - let preceding_chars_start = s[..closing].rfind("\n").map_or(0, |i| i + 1); - if s[preceding_chars_start..closing].chars().all(is_whitespace) { - // candidate found - self.bump_bytes(size + closing); - // in case like - // ---cargo - // --- blahblah - // or - // ---cargo - // ---- - // combine those stuff into this frontmatter token such that it gets detected later. - self.eat_until(b'\n'); - found = true; - break; - } else { - s = &s[closing + length_opening as usize..]; - size += closing + length_opening as usize; - } + let nl_fence_pattern = format!("\n{:-<1$}", "", length_opening as usize); + if let Some(closing) = self.as_str().find(&nl_fence_pattern) { + // candidate found + self.bump_bytes(closing + nl_fence_pattern.len()); + // in case like + // ---cargo + // --- blahblah + // or + // ---cargo + // ---- + // combine those stuff into this frontmatter token such that it gets detected later. + self.eat_until(b'\n'); + found = true; } if !found { @@ -594,14 +599,16 @@ impl Cursor<'_> { if potential_closing.is_none() { // a less fortunate recovery if all else fails which finds any dashes preceded by whitespace // on a standalone line. Might be wrong. + let mut base_index = 0; while let Some(closing) = rest.find("---") { let preceding_chars_start = rest[..closing].rfind("\n").map_or(0, |i| i + 1); - if rest[preceding_chars_start..closing].chars().all(is_whitespace) { + if rest[preceding_chars_start..closing].chars().all(is_horizontal_whitespace) { // candidate found - potential_closing = Some(closing); + potential_closing = Some(closing + base_index); break; } else { rest = &rest[closing + 3..]; + base_index += closing + 3; } } } |
