about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-09-01 17:35:04 +1000
committerGitHub <noreply@github.com>2025-09-01 17:35:04 +1000
commit0972fd9d4188dc0bbe3db7f4f44344591af1f3ef (patch)
treed0e6b153ef115504aed80be74db538a14e934460
parent88c254f8d4bf6ee21cd39582d5974915d71c42b3 (diff)
parent142e25e35621b7043cc86bdc3d74f463ca2032d1 (diff)
downloadrust-0972fd9d4188dc0bbe3db7f4f44344591af1f3ef.tar.gz
rust-0972fd9d4188dc0bbe3db7f4f44344591af1f3ef.zip
Rollup merge of #145754 - epage:escape, r=SparrowLii
fix(lexer): Don't require frontmatters to be escaped with indented fences

The RFC only limits hyphens at the beginning of lines and not if they are indented or embedded in other content.

Sticking to that approach was confirmed by the T-lang liason at https://github.com/rust-lang/rust/issues/141367#issuecomment-3202217544

There is a regression in error message quality which I'm leaving for someone if they feel this needs improving.

Tracking issue: rust-lang/rust#136889

Fixes rust-lang/rust#141367
-rw-r--r--compiler/rustc_lexer/src/lib.rs34
-rw-r--r--tests/ui/frontmatter/frontmatter-whitespace-1.rs2
-rw-r--r--tests/ui/frontmatter/frontmatter-whitespace-1.stderr18
-rw-r--r--tests/ui/frontmatter/frontmatter-whitespace-2.rs5
-rw-r--r--tests/ui/frontmatter/frontmatter-whitespace-2.stderr38
-rw-r--r--tests/ui/frontmatter/multifrontmatter-2.rs6
-rw-r--r--tests/ui/frontmatter/multifrontmatter-2.stderr22
7 files changed, 51 insertions, 74 deletions
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index 483cc3e93dc..d10b1920343 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -550,28 +550,20 @@ impl Cursor<'_> {
         self.eat_while(|ch| ch != '\n' && is_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 {
diff --git a/tests/ui/frontmatter/frontmatter-whitespace-1.rs b/tests/ui/frontmatter/frontmatter-whitespace-1.rs
index 8b6e2d1af84..3b7f762d26e 100644
--- a/tests/ui/frontmatter/frontmatter-whitespace-1.rs
+++ b/tests/ui/frontmatter/frontmatter-whitespace-1.rs
@@ -1,7 +1,7 @@
   ---
 //~^ ERROR: invalid preceding whitespace for frontmatter opening
+//~^^ ERROR: unclosed frontmatter
   ---
-//~^ ERROR: invalid preceding whitespace for frontmatter close
 
 #![feature(frontmatter)]
 
diff --git a/tests/ui/frontmatter/frontmatter-whitespace-1.stderr b/tests/ui/frontmatter/frontmatter-whitespace-1.stderr
index 37ece27acb2..f16788fa399 100644
--- a/tests/ui/frontmatter/frontmatter-whitespace-1.stderr
+++ b/tests/ui/frontmatter/frontmatter-whitespace-1.stderr
@@ -10,17 +10,21 @@ note: frontmatter opening should not be preceded by whitespace
 LL |   ---
    | ^^
 
-error: invalid preceding whitespace for frontmatter close
-  --> $DIR/frontmatter-whitespace-1.rs:3:1
+error: unclosed frontmatter
+  --> $DIR/frontmatter-whitespace-1.rs:1:3
    |
-LL |   ---
-   | ^^^^^
+LL | /   ---
+LL | |
+LL | |
+LL | |   ---
+LL | |
+   | |_^
    |
-note: frontmatter close should not be preceded by whitespace
-  --> $DIR/frontmatter-whitespace-1.rs:3:1
+note: frontmatter opening here was not closed
+  --> $DIR/frontmatter-whitespace-1.rs:1:3
    |
 LL |   ---
-   | ^^
+   |   ^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/frontmatter/frontmatter-whitespace-2.rs b/tests/ui/frontmatter/frontmatter-whitespace-2.rs
index e8c100849b4..7a28e5c1b85 100644
--- a/tests/ui/frontmatter/frontmatter-whitespace-2.rs
+++ b/tests/ui/frontmatter/frontmatter-whitespace-2.rs
@@ -1,4 +1,5 @@
 ---cargo
+//~^ ERROR: unclosed frontmatter
 
 //@ compile-flags: --crate-type lib
 
@@ -6,10 +7,8 @@
 
 fn foo(x: i32) -> i32 {
     ---x
-    //~^ ERROR: invalid preceding whitespace for frontmatter close
-    //~| ERROR: extra characters after frontmatter close are not allowed
+     //~^ WARNING: use of a double negation [double_negations]
 }
-//~^ ERROR: unexpected closing delimiter: `}`
 
 // this test is for the weird case that valid Rust code can have three dashes
 // within them and get treated as a frontmatter close.
diff --git a/tests/ui/frontmatter/frontmatter-whitespace-2.stderr b/tests/ui/frontmatter/frontmatter-whitespace-2.stderr
index ada6af0ec04..2ae63cdc6fe 100644
--- a/tests/ui/frontmatter/frontmatter-whitespace-2.stderr
+++ b/tests/ui/frontmatter/frontmatter-whitespace-2.stderr
@@ -1,26 +1,30 @@
-error: invalid preceding whitespace for frontmatter close
-  --> $DIR/frontmatter-whitespace-2.rs:8:1
+error: unclosed frontmatter
+  --> $DIR/frontmatter-whitespace-2.rs:1:1
    |
-LL |     ---x
-   | ^^^^^^^^
+LL | / ---cargo
+...  |
+LL | |
+   | |_^
    |
-note: frontmatter close should not be preceded by whitespace
-  --> $DIR/frontmatter-whitespace-2.rs:8:1
+note: frontmatter opening here was not closed
+  --> $DIR/frontmatter-whitespace-2.rs:1:1
    |
-LL |     ---x
-   | ^^^^
+LL | ---cargo
+   | ^^^
 
-error: extra characters after frontmatter close are not allowed
-  --> $DIR/frontmatter-whitespace-2.rs:8:1
+warning: use of a double negation
+  --> $DIR/frontmatter-whitespace-2.rs:9:6
    |
 LL |     ---x
-   | ^^^^^^^^
-
-error: unexpected closing delimiter: `}`
-  --> $DIR/frontmatter-whitespace-2.rs:11:1
+   |      ^^^
+   |
+   = note: the prefix `--` could be misinterpreted as a decrement operator which exists in other languages
+   = note: use `-= 1` if you meant to decrement the value
+   = note: `#[warn(double_negations)]` on by default
+help: add parentheses for clarity
    |
-LL | }
-   | ^ unexpected closing delimiter
+LL |     --(-x)
+   |       +  +
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/frontmatter/multifrontmatter-2.rs b/tests/ui/frontmatter/multifrontmatter-2.rs
index 33cc30cb465..8e5b45a0bf7 100644
--- a/tests/ui/frontmatter/multifrontmatter-2.rs
+++ b/tests/ui/frontmatter/multifrontmatter-2.rs
@@ -1,12 +1,12 @@
 ---
  ---
-//~^ ERROR: invalid preceding whitespace for frontmatter close
 
  ---
-//~^ ERROR: expected item, found `-`
-// FIXME(frontmatter): make this diagnostic better
 ---
 
+// hyphens only need to be escaped when at the start of a line
+//@ check-pass
+
 #![feature(frontmatter)]
 
 fn main() {}
diff --git a/tests/ui/frontmatter/multifrontmatter-2.stderr b/tests/ui/frontmatter/multifrontmatter-2.stderr
deleted file mode 100644
index ed9ac4029e2..00000000000
--- a/tests/ui/frontmatter/multifrontmatter-2.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error: invalid preceding whitespace for frontmatter close
-  --> $DIR/multifrontmatter-2.rs:2:1
-   |
-LL |  ---
-   | ^^^^
-   |
-note: frontmatter close should not be preceded by whitespace
-  --> $DIR/multifrontmatter-2.rs:2:1
-   |
-LL |  ---
-   | ^
-
-error: expected item, found `-`
-  --> $DIR/multifrontmatter-2.rs:5:2
-   |
-LL |  ---
-   |  ^ expected item
-   |
-   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
-
-error: aborting due to 2 previous errors
-