diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 449d0b964fd4..3f3300117460 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -98,6 +98,8 @@ parse_bare_cr = {$double_quotes -> } .escape = escape the character +parse_bare_cr_in_frontmatter = bare CR not allowed in frontmatter + parse_bare_cr_in_raw_string = bare CR not allowed in raw string 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 parse_frontmatter_too_many_dashes = too many `-` symbols: frontmatter openings may be delimited by up to 255 `-` symbols, but found {$len_opening} parse_frontmatter_unclosed = unclosed frontmatter .note = frontmatter opening here was not closed - parse_function_body_equals_expr = function body cannot be `= expression;` .suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;` diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 42327c7e343d..4e789a321649 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -829,6 +829,13 @@ pub(crate) struct FrontmatterTooManyDashes { pub len_opening: usize, } +#[derive(Diagnostic)] +#[diag(parse_bare_cr_in_frontmatter)] +pub(crate) struct BareCrFrontmatter { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(parse_leading_plus_not_supported)] pub(crate) struct LeadingPlusNotSupported { diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 4d0139e179f4..f9bf50de091a 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -614,8 +614,8 @@ fn validate_frontmatter( }); } + let line_end = real_s.find('\n').unwrap_or(real_s.len()); if invalid_infostring { - let line_end = real_s.find('\n').unwrap_or(real_s.len()); let span = self.mk_sp( frontmatter_opening_end_pos, frontmatter_opening_pos + BytePos(line_end as u32), @@ -624,6 +624,14 @@ fn validate_frontmatter( } let last_line_start = real_s.rfind('\n').map_or(0, |i| i + 1); + + let content = &real_s[line_end..last_line_start]; + if let Some(cr_offset) = content.find('\r') { + let cr_pos = start + BytePos((real_start + line_end + cr_offset) as u32); + let span = self.mk_sp(cr_pos, cr_pos + BytePos(1 as u32)); + self.dcx().emit_err(errors::BareCrFrontmatter { span }); + } + let last_line = &real_s[last_line_start..]; let last_line_trimmed = last_line.trim_start_matches(is_horizontal_whitespace); let last_line_start_pos = frontmatter_opening_pos + BytePos(last_line_start as u32); diff --git a/tests/ui/frontmatter/content-cr.rs b/tests/ui/frontmatter/content-cr.rs index 768282fc2b93..71bede928f37 100644 --- a/tests/ui/frontmatter/content-cr.rs +++ b/tests/ui/frontmatter/content-cr.rs @@ -1,10 +1,9 @@ --- -package.name = " " +package.name = " " # //~ ERROR bare CR not allowed in frontmatter package.description = "é" --- // ignore-tidy-cr -//@ check-pass #![feature(frontmatter)] diff --git a/tests/ui/frontmatter/content-cr.stderr b/tests/ui/frontmatter/content-cr.stderr new file mode 100644 index 000000000000..d59b899cc4c3 --- /dev/null +++ b/tests/ui/frontmatter/content-cr.stderr @@ -0,0 +1,8 @@ +error: bare CR not allowed in frontmatter + --> $DIR/content-cr.rs:2:17 + | +LL | package.name = "␍" # + | ^ + +error: aborting due to 1 previous error +