Skip to content

Commit 91e3b8c

Browse files
authored
Unrolled build for #149823
Rollup merge of #149823 - epage:f, r=Kivooeo fix(parser): Disallow CR in frontmatter T-lang came back on the stabilization PR (#148051) asking for CR to be disallowed to leave room for all stray CRs to be rejected in the future. At that point, the test can remain but the implementation can be removed. If that plan does not go through, we'll need to re-evaluate - whether this is more lint-like and should defer to the calling tool that is managing the frontmatter - how much Rust should treat the frontmatter as Rust and apply the same grammar restrictions of "no stray CR" (like raw string literals) Part of #136889
2 parents 80b8982 + 52d4ef1 commit 91e3b8c

5 files changed

Lines changed: 42 additions & 8 deletions

File tree

compiler/rustc_parse/messages.ftl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ parse_bare_cr = {$double_quotes ->
9898
}
9999
.escape = escape the character
100100
101+
parse_bare_cr_in_frontmatter = bare CR not allowed in frontmatter
102+
101103
parse_bare_cr_in_raw_string = bare CR not allowed in raw string
102104
103105
parse_binder_and_polarity = `for<...>` binder not allowed with `{$polarity}` trait polarity modifier
@@ -352,7 +354,6 @@ parse_frontmatter_length_mismatch = frontmatter close does not match the opening
352354
parse_frontmatter_too_many_dashes = too many `-` symbols: frontmatter openings may be delimited by up to 255 `-` symbols, but found {$len_opening}
353355
parse_frontmatter_unclosed = unclosed frontmatter
354356
.note = frontmatter opening here was not closed
355-
356357
parse_function_body_equals_expr = function body cannot be `= expression;`
357358
.suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;`
358359

compiler/rustc_parse/src/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,13 @@ pub(crate) struct FrontmatterTooManyDashes {
829829
pub len_opening: usize,
830830
}
831831

832+
#[derive(Diagnostic)]
833+
#[diag(parse_bare_cr_in_frontmatter)]
834+
pub(crate) struct BareCrFrontmatter {
835+
#[primary_span]
836+
pub span: Span,
837+
}
838+
832839
#[derive(Diagnostic)]
833840
#[diag(parse_leading_plus_not_supported)]
834841
pub(crate) struct LeadingPlusNotSupported {

compiler/rustc_parse/src/lexer/mod.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -598,9 +598,9 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
598598
let s = self.str_from(start);
599599
let real_start = s.find("---").unwrap();
600600
let frontmatter_opening_pos = BytePos(real_start as u32) + start;
601-
let s_new = &s[real_start..];
602-
let within = s_new.trim_start_matches('-');
603-
let len_opening = s_new.len() - within.len();
601+
let real_s = &s[real_start..];
602+
let within = real_s.trim_start_matches('-');
603+
let len_opening = real_s.len() - within.len();
604604

605605
let frontmatter_opening_end_pos = frontmatter_opening_pos + BytePos(len_opening as u32);
606606
if has_invalid_preceding_whitespace {
@@ -614,19 +614,27 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
614614
});
615615
}
616616

617+
let line_end = real_s.find('\n').unwrap_or(real_s.len());
617618
if invalid_infostring {
618-
let line_end = s[real_start..].find('\n').unwrap_or(s[real_start..].len());
619619
let span = self.mk_sp(
620620
frontmatter_opening_end_pos,
621621
frontmatter_opening_pos + BytePos(line_end as u32),
622622
);
623623
self.dcx().emit_err(errors::FrontmatterInvalidInfostring { span });
624624
}
625625

626-
let last_line_start = within.rfind('\n').map_or(0, |i| i + 1);
627-
let last_line = &within[last_line_start..];
626+
let last_line_start = real_s.rfind('\n').map_or(0, |i| i + 1);
627+
628+
let content = &real_s[line_end..last_line_start];
629+
if let Some(cr_offset) = content.find('\r') {
630+
let cr_pos = start + BytePos((real_start + line_end + cr_offset) as u32);
631+
let span = self.mk_sp(cr_pos, cr_pos + BytePos(1 as u32));
632+
self.dcx().emit_err(errors::BareCrFrontmatter { span });
633+
}
634+
635+
let last_line = &real_s[last_line_start..];
628636
let last_line_trimmed = last_line.trim_start_matches(is_horizontal_whitespace);
629-
let last_line_start_pos = frontmatter_opening_end_pos + BytePos(last_line_start as u32);
637+
let last_line_start_pos = frontmatter_opening_pos + BytePos(last_line_start as u32);
630638

631639
let frontmatter_span = self.mk_sp(frontmatter_opening_pos, self.pos);
632640
self.psess.gated_spans.gate(sym::frontmatter, frontmatter_span);

tests/ui/frontmatter/content-cr.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
package.name = "" # //~ ERROR bare CR not allowed in frontmatter
3+
package.description = "é"
4+
---
5+
6+
// ignore-tidy-cr
7+
8+
#![feature(frontmatter)]
9+
10+
pub fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: bare CR not allowed in frontmatter
2+
--> $DIR/content-cr.rs:2:17
3+
|
4+
LL | package.name = "␍" #
5+
| ^
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)