From fafe84b7c1e5bde99d5546d9067a112b5a9cc980 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 9 Oct 2025 14:01:04 -0500 Subject: [PATCH 01/12] docs(ref): Specify frontmatter Edited-by: TC Fixed conflicts due to rust-lang/reference#2199. No other changes. --- src/SUMMARY.md | 1 + src/frontmatter.md | 58 ++++++++++++++++++++++++++++++++++++++++++++ src/input-format.md | 8 +++++- src/items/modules.md | 2 +- 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/frontmatter.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 0692b3f433..2fa3622266 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -7,6 +7,7 @@ - [Lexical structure](lexical-structure.md) - [Input format](input-format.md) - [Shebang](shebang.md) + - [Frontmatter](frontmatter.md) - [Keywords](keywords.md) - [Identifiers](identifiers.md) - [Comments](comments.md) diff --git a/src/frontmatter.md b/src/frontmatter.md new file mode 100644 index 0000000000..388f9232f5 --- /dev/null +++ b/src/frontmatter.md @@ -0,0 +1,58 @@ +r[frontmatter] +# Frontmatter + +r[frontmatter.syntax] +```grammar,lexer +@root FRONTMATTER -> + FRONTMATTER_FENCE HORIZONTAL_WHITESPACE* INFOSTRING? HORIZONTAL_WHITESPACE* LF + (FRONTMATTER_LINE LF )* + FRONTMATTER_FENCE[^matched-fence] HORIZONTAL_WHITESPACE* LF + +FRONTMATTER_FENCE -> `-`{3..255} + +INFOSTRING -> (XID_Start | `_`) ( XID_Continue | `-` | `.` )* + +FRONTMATTER_LINE -> (~INVALID_FRONTMATTER_LINE_START (~INVALID_FRONTMATTER_LINE_CONTINUE)*)? + +INVALID_FRONTMATTER_LINE_START -> (FRONTMATTER_FENCE[^escaped-fence] | CR | LF) + +INVALID_FRONTMATTER_LINE_CONTINUE -> CR | LF + +HORIZONTAL_WHITESPACE -> + U+0009 // horizontal tab, `'\t'` + | U+0020 // space, `' '` +``` + +[^matched-fence]: The closing fence must have the same number of `-` as the opening fence +[^escaped-fence]: A `FRONTMATTER_FENCE` at the beginning of a `FRONTMATTER_LINE` is only invalid if it has the same or more `-` as the `FRONTMATTER_FENCE` + +r[frontmatter.intro] +Frontmatter is an optional section for content intended for external tools without requiring these tools to have full knowledge of the Rust grammar. + +```rust +#!/usr/bin/env cargo +--- +[dependencies] +fastrand = "2" +--- + +fn main() { + let num = fastrand::i32(..); + println!("{num}"); +} +``` + +r[frontmatter.document] +Frontmatter may only be preceded by a [shebang] and [whitespace]. + +r[frontmatter.fence] +The delimiters are referred to as a *fence*. The opening and closing fences must be at the start of a line. They must be a matching pair of hyphens (`-`), from 3 to 255. A fence may be followed by horizontal whitespace. + +r[frontmatter.infostring] +Following the opening fence may be an infostring for identifying the intention of the contained content. An infostring may be followed by horizontal whitespace. + +r[frontmatter.body] +The body of the frontmatter may contain any content except for a line starting with as many or more hyphens (`-`) than in the fences or carriage returns. + +[shebang]: input-format.md#shebang-removal +[whitespace]: whitespace.md diff --git a/src/input-format.md b/src/input-format.md index 88ab3658ba..fc7f43d772 100644 --- a/src/input-format.md +++ b/src/input-format.md @@ -44,6 +44,11 @@ r[input.shebang] r[input.shebang.removal] If a [shebang] is present, it is removed from the input sequence (and is therefore ignored). +r[input.frontmatter] +## Frontmatter removal + +After some [whitespace], [frontmatter] may next appear in the input. + r[input.tokenization] ## Tokenization @@ -54,11 +59,12 @@ The resulting sequence of characters is then converted into tokens as described > > - Byte order mark removal. > - CRLF normalization. -> - Shebang removal when invoked in an item context (as opposed to expression or statement contexts). +> - Shebang and frontmatter removal when invoked in an item context (as opposed to expression or statement contexts). > > The [`include_str!`] and [`include_bytes!`] macros do not apply these transformations. [BYTE ORDER MARK]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 [Crates and source files]: crates-and-source-files.md +[frontmatter]: frontmatter.md [shebang]: shebang.md [whitespace]: whitespace.md diff --git a/src/items/modules.md b/src/items/modules.md index 3cc015025b..2164051f84 100644 --- a/src/items/modules.md +++ b/src/items/modules.md @@ -123,7 +123,7 @@ r[items.mod.attributes] ## Attributes on modules r[items.mod.attributes.intro] -Modules, like all items, accept outer attributes. They also accept inner attributes: either after `{` for a module with a body, or at the beginning of the source file, after the optional BOM and shebang. +Modules, like all items, accept outer attributes. They also accept inner attributes: either after `{` for a module with a body, or at the beginning of the source file, after the optional BOM, shebang, and frontmatter. r[items.mod.attributes.supported] The built-in attributes that have meaning on a module are [`cfg`], [`deprecated`], [`doc`], [the lint check attributes], [`path`], and [`no_implicit_prelude`]. Modules also accept macro attributes. From 5f5eff9327669a540c6d8b0f6519327712c112a2 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 4 Feb 2026 02:25:32 +0000 Subject: [PATCH 02/12] =?UTF-8?q?Revise=20frontmatter=20grammar;=20add=20?= =?UTF-8?q?=E2=8A=A5=20rule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prior commit added a grammar for frontmatter, but the grammar notation available at the time that commit was prepared couldn't express all of the invariants the language requires. Opening and closing fences must have the same dash count. Indented fences must be rejected as an error. And once an opening fence is recognized, the parser must commit -- it can't backtrack and reinterpret the dashes as tokens. Since then, we've added named range repeats, hard cut, and negative lookahead to the grammar notation. With these, we can express the invariants directly. In this commit, we rewrite the frontmatter grammar. Named range repeats let the closing fence reference the opening fence's dash count. Hard cut commits the parse after the opening dashes. And `FRONTMATTER_INVALID` uses hard cut followed by the bottom rule (`^ ⊥`) to express that indented fences are a recognized-and-rejected syntactic form. We also add `⊥` as a primitive rule in the Notation chapter, move `HORIZONTAL_WHITESPACE` to Whitespace, and fix some minor editorial matters such as indentation and comment style. --- src/frontmatter.md | 36 ++++++++++++++++++++++-------------- src/notation.md | 12 ++++++++++++ src/whitespace.md | 4 ++++ 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/frontmatter.md b/src/frontmatter.md index 388f9232f5..f1d1df16ea 100644 --- a/src/frontmatter.md +++ b/src/frontmatter.md @@ -4,27 +4,35 @@ r[frontmatter] r[frontmatter.syntax] ```grammar,lexer @root FRONTMATTER -> - FRONTMATTER_FENCE HORIZONTAL_WHITESPACE* INFOSTRING? HORIZONTAL_WHITESPACE* LF - (FRONTMATTER_LINE LF )* - FRONTMATTER_FENCE[^matched-fence] HORIZONTAL_WHITESPACE* LF + WHITESPACE_ONLY_LINE* + !FRONTMATTER_INVALID + FRONTMATTER_MAIN -FRONTMATTER_FENCE -> `-`{3..255} +WHITESPACE_ONLY_LINE -> (!LF WHITESPACE)* LF -INFOSTRING -> (XID_Start | `_`) ( XID_Continue | `-` | `.` )* +FRONTMATTER_INVALID -> (!LF WHITESPACE)+ `---` ^ ⊥ -FRONTMATTER_LINE -> (~INVALID_FRONTMATTER_LINE_START (~INVALID_FRONTMATTER_LINE_CONTINUE)*)? +FRONTMATTER_MAIN -> + `-`{n:3..=255} ^ FRONTMATTER_REST -INVALID_FRONTMATTER_LINE_START -> (FRONTMATTER_FENCE[^escaped-fence] | CR | LF) +FRONTMATTER_REST -> + FRONTMATTER_FENCE_START + FRONTMATTER_LINE* + FRONTMATTER_FENCE_END -INVALID_FRONTMATTER_LINE_CONTINUE -> CR | LF +FRONTMATTER_FENCE_START -> + MAYBE_INFOSTRING_OR_WS LF -HORIZONTAL_WHITESPACE -> - U+0009 // horizontal tab, `'\t'` - | U+0020 // space, `' '` -``` +FRONTMATTER_FENCE_END -> + `-`{n} HORIZONTAL_WHITESPACE* ( LF | EOF ) + +FRONTMATTER_LINE -> !`-`{n} ~[LF CR]* LF -[^matched-fence]: The closing fence must have the same number of `-` as the opening fence -[^escaped-fence]: A `FRONTMATTER_FENCE` at the beginning of a `FRONTMATTER_LINE` is only invalid if it has the same or more `-` as the `FRONTMATTER_FENCE` +MAYBE_INFOSTRING_OR_WS -> + HORIZONTAL_WHITESPACE* INFOSTRING? HORIZONTAL_WHITESPACE* + +INFOSTRING -> (XID_Start | `_`) ( XID_Continue | `-` | `.` )* +``` r[frontmatter.intro] Frontmatter is an optional section for content intended for external tools without requiring these tools to have full knowledge of the Rust grammar. diff --git a/src/notation.md b/src/notation.md index 7537c67ddc..ed21e6a386 100644 --- a/src/notation.md +++ b/src/notation.md @@ -45,6 +45,18 @@ Mizushima et al. introduced [cut operators][cut operator paper] to parsing expre The hard cut operator is necessary because some tokens in Rust begin with a prefix that is itself a valid token. For example, `c"` begins a C string literal, but `c` alone is a valid identifier. Without the cut, if `c"\0"` failed to lex as a C string literal (because null bytes are not allowed in C strings), the parser could backtrack and lex it as two tokens: the identifier `c` and the string literal `"\0"`. The [cut after `c"`] prevents this --- once the opening delimiter is recognized, the parser cannot go back. The same reasoning applies to [byte literals], [byte string literals], [raw string literals], and other literals with prefixes that are themselves valid tokens. +r[notation.grammar.bottom] +### The bottom rule + +In logic, ⊥ (*bottom*) represents *absurdity* --- a proposition that is always false. In type theory, it is the *empty type* --- a type with no inhabitants. The grammar borrows both senses: the rule ⊥ matches nothing --- not any character, not even the end of input. + +```grammar,notation +// The bottom rule does not match anything. +⊥ -> !(CHAR | EOF) +``` + +Placed after a [hard cut operator], ⊥ makes a rule fail unconditionally once the parser has committed past the cut. This gives the grammar a way to express recognition without acceptance. The parser identifies the input, commits so that no other alternative can be tried, and then rejects it. In the frontmatter grammar, for example, [FRONTMATTER_INVALID] uses `^ ⊥` to recognize an opening fence preceded by whitespace on the same line --- input that is close enough to frontmatter to rule out other interpretations but is not valid. + r[notation.grammar.string-tables] ### String table productions diff --git a/src/whitespace.md b/src/whitespace.md index 7e16c51d41..25f33ee1c6 100644 --- a/src/whitespace.md +++ b/src/whitespace.md @@ -16,6 +16,10 @@ WHITESPACE -> | U+2028 // Line separator | U+2029 // Paragraph separator +HORIZONTAL_WHITESPACE -> + U+0009 // Horizontal tab, `'\t'` + | U+0020 // Space, `' '` + TAB -> U+0009 // Horizontal tab, `'\t'` LF -> U+000A // Line feed, `'\n'` From a60ca223f45f6c12e788cf54ad68d7dac12e1f72 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 25 Feb 2026 06:54:53 +0000 Subject: [PATCH 03/12] Clarify the fence description The fence description uses the phrase "a matching pair of hyphens", which can be misread as describing exactly two individual hyphens. The constraints on fence length and matching are also compressed into a single sentence with a trailing subclause ("from 3 to 255") that reads as nonrestrictive. Let's give each constraint its own sentence: what a fence is, where it must appear, the length bounds on the opening fence, the matching requirement for the closing fence, and trailing whitespace. This makes the structure clearer. --- src/frontmatter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontmatter.md b/src/frontmatter.md index f1d1df16ea..87eb70acf7 100644 --- a/src/frontmatter.md +++ b/src/frontmatter.md @@ -54,7 +54,7 @@ r[frontmatter.document] Frontmatter may only be preceded by a [shebang] and [whitespace]. r[frontmatter.fence] -The delimiters are referred to as a *fence*. The opening and closing fences must be at the start of a line. They must be a matching pair of hyphens (`-`), from 3 to 255. A fence may be followed by horizontal whitespace. +Frontmatter must start and end with a *fence*. Each fence must start at the beginning of a line. The opening fence must consist of at least 3 and no more than 255 hyphens (`-`). The closing fence must have exactly the same number of hyphens as the opening fence. The hyphens of either fence may be followed by horizontal whitespace. r[frontmatter.infostring] Following the opening fence may be an infostring for identifying the intention of the contained content. An infostring may be followed by horizontal whitespace. From 0840484f014d9801de759cf413256f976bb66b83 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 25 Feb 2026 06:55:13 +0000 Subject: [PATCH 04/12] Revise the infostring description The infostring sentence uses an inverted construction ("Following the opening fence may be an infostring"); it's a bit awkward. Let's use active voice and tighten the phrasing. --- src/frontmatter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontmatter.md b/src/frontmatter.md index 87eb70acf7..b65ae6a131 100644 --- a/src/frontmatter.md +++ b/src/frontmatter.md @@ -57,7 +57,7 @@ r[frontmatter.fence] Frontmatter must start and end with a *fence*. Each fence must start at the beginning of a line. The opening fence must consist of at least 3 and no more than 255 hyphens (`-`). The closing fence must have exactly the same number of hyphens as the opening fence. The hyphens of either fence may be followed by horizontal whitespace. r[frontmatter.infostring] -Following the opening fence may be an infostring for identifying the intention of the contained content. An infostring may be followed by horizontal whitespace. +The opening fence, after optional horizontal whitespace, may be followed by an infostring that identifies the format or purpose of the body. An infostring may be followed by horizontal whitespace. r[frontmatter.body] The body of the frontmatter may contain any content except for a line starting with as many or more hyphens (`-`) than in the fences or carriage returns. From 69f90affe862084db649b19cd8f105da3bbeb4ec Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 25 Feb 2026 06:55:29 +0000 Subject: [PATCH 05/12] Clarify the body restrictions The body restriction sentence combines two unrelated constraints -- the hyphen-line restriction and the carriage-return ban -- in a single sentence joined by "or". This makes "or carriage returns" read as parallel to "hyphens", as though the line could maybe start with carriage returns. Let's split these into two separate sentences so that each constraint stands on its own. --- src/frontmatter.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontmatter.md b/src/frontmatter.md index b65ae6a131..b5d6287d80 100644 --- a/src/frontmatter.md +++ b/src/frontmatter.md @@ -60,7 +60,8 @@ r[frontmatter.infostring] The opening fence, after optional horizontal whitespace, may be followed by an infostring that identifies the format or purpose of the body. An infostring may be followed by horizontal whitespace. r[frontmatter.body] -The body of the frontmatter may contain any content except for a line starting with as many or more hyphens (`-`) than in the fences or carriage returns. +No line in the body may start with a sequence of hyphens (`-`) equal to or longer than the opening fence. The body may not contain any carriage returns (that survive [CRLF normalization]). +[CRLF normalization]: input.crlf [shebang]: input-format.md#shebang-removal [whitespace]: whitespace.md From 87d591496433b3942e444990e4273546a96772ac Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 25 Feb 2026 06:55:45 +0000 Subject: [PATCH 06/12] Link horizontal whitespace to the grammar rule The prose mentions "horizontal whitespace" in two places (fence trailing content and infostring trailing content) without linking to the grammar definition. Since `HORIZONTAL_WHITESPACE` is now a defined rule in Whitespace, let's add a link so readers can click through to the precise definition. --- src/frontmatter.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frontmatter.md b/src/frontmatter.md index b5d6287d80..ba81c7528a 100644 --- a/src/frontmatter.md +++ b/src/frontmatter.md @@ -54,14 +54,15 @@ r[frontmatter.document] Frontmatter may only be preceded by a [shebang] and [whitespace]. r[frontmatter.fence] -Frontmatter must start and end with a *fence*. Each fence must start at the beginning of a line. The opening fence must consist of at least 3 and no more than 255 hyphens (`-`). The closing fence must have exactly the same number of hyphens as the opening fence. The hyphens of either fence may be followed by horizontal whitespace. +Frontmatter must start and end with a *fence*. Each fence must start at the beginning of a line. The opening fence must consist of at least 3 and no more than 255 hyphens (`-`). The closing fence must have exactly the same number of hyphens as the opening fence. The hyphens of either fence may be followed by [horizontal whitespace]. r[frontmatter.infostring] -The opening fence, after optional horizontal whitespace, may be followed by an infostring that identifies the format or purpose of the body. An infostring may be followed by horizontal whitespace. +The opening fence, after optional [horizontal whitespace], may be followed by an infostring that identifies the format or purpose of the body. An infostring may be followed by horizontal whitespace. r[frontmatter.body] No line in the body may start with a sequence of hyphens (`-`) equal to or longer than the opening fence. The body may not contain any carriage returns (that survive [CRLF normalization]). [CRLF normalization]: input.crlf +[horizontal whitespace]: grammar-HORIZONTAL_WHITESPACE [shebang]: input-format.md#shebang-removal [whitespace]: whitespace.md From d978d31a1ab7f96970f6163064aa876f24cef77c Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 25 Feb 2026 06:56:12 +0000 Subject: [PATCH 07/12] Flesh out the frontmatter removal section The frontmatter removal section could do better at describing the removal behavior. Let's rewrite the section with a precise description of the removal process and add an annotated example. --- src/input-format.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/input-format.md b/src/input-format.md index fc7f43d772..1e5432feff 100644 --- a/src/input-format.md +++ b/src/input-format.md @@ -47,7 +47,21 @@ If a [shebang] is present, it is removed from the input sequence (and is therefo r[input.frontmatter] ## Frontmatter removal -After some [whitespace], [frontmatter] may next appear in the input. +r[input.frontmatter.removal] +If the remaining input begins with a [frontmatter] fence, optionally preceded by lines containing only [whitespace], the [frontmatter] and any preceding whitespace are removed. + +For example, given the following file: + + +```rust,ignore +--- cargo +package.edition = "2024" +--- + +fn main() {} +``` + +The first three lines (the opening fence, body, and closing fence) would be removed, leaving an empty line followed by `fn main() {}`. r[input.tokenization] ## Tokenization From 432b613d95856f987ecc258a655b98ea93eccbc5 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 4 Mar 2026 01:16:21 +0000 Subject: [PATCH 08/12] Clarify frontmatter position rule The `frontmatter.document` rule said "Frontmatter may only be preceded by a shebang and whitespace", where the "and" could be misread as requiring both a shebang and whitespace rather than listing the set of things allowed to precede frontmatter. Since we merged the shebang prose revision (rust-lang/reference#2192), the shebang position rule now reads as a positive statement of where the shebang may appear. Let's follow the same pattern here: state positively where frontmatter may appear rather than leaning on "only" and a negative constraint. We'll also rename the rule identifier to `frontmatter.position` in keeping with our conventions. --- src/frontmatter.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frontmatter.md b/src/frontmatter.md index ba81c7528a..d5b38e6702 100644 --- a/src/frontmatter.md +++ b/src/frontmatter.md @@ -50,8 +50,8 @@ fn main() { } ``` -r[frontmatter.document] -Frontmatter may only be preceded by a [shebang] and [whitespace]. +r[frontmatter.position] +Frontmatter may appear at the start of the file (after the optional [byte order mark]) or after a [shebang]. In either case, it may be preceded by [whitespace]. r[frontmatter.fence] Frontmatter must start and end with a *fence*. Each fence must start at the beginning of a line. The opening fence must consist of at least 3 and no more than 255 hyphens (`-`). The closing fence must have exactly the same number of hyphens as the opening fence. The hyphens of either fence may be followed by [horizontal whitespace]. @@ -62,6 +62,7 @@ The opening fence, after optional [horizontal whitespace], may be followed by an r[frontmatter.body] No line in the body may start with a sequence of hyphens (`-`) equal to or longer than the opening fence. The body may not contain any carriage returns (that survive [CRLF normalization]). +[byte order mark]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 [CRLF normalization]: input.crlf [horizontal whitespace]: grammar-HORIZONTAL_WHITESPACE [shebang]: input-format.md#shebang-removal From 5d79ac6dde6718ce59e3e921f357ce444b16748b Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 4 Mar 2026 01:23:03 +0000 Subject: [PATCH 09/12] Revise frontmatter intro example The example under `frontmatter.intro` used an external crate, a nontrivial script body, and a bare `rust` code block that would fail CI since the test runner doesn't support frontmatter. Let's simplify it to mirror the example in the frontmatter removal section of `input-format.md`, and let's wrap it in an `EXAMPLE` admonition consistent with our convention for examples that aren't demonstrating the behavior of a specific rule. --- src/frontmatter.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/frontmatter.md b/src/frontmatter.md index d5b38e6702..f32064ec39 100644 --- a/src/frontmatter.md +++ b/src/frontmatter.md @@ -37,18 +37,16 @@ INFOSTRING -> (XID_Start | `_`) ( XID_Continue | `-` | `.` )* r[frontmatter.intro] Frontmatter is an optional section for content intended for external tools without requiring these tools to have full knowledge of the Rust grammar. -```rust -#!/usr/bin/env cargo ---- -[dependencies] -fastrand = "2" ---- - -fn main() { - let num = fastrand::i32(..); - println!("{num}"); -} -``` +> [!EXAMPLE] +> +> ```rust,ignore +> #!/bin/env cargo +> --- cargo +> package.edition = "2024" +> --- +> +> fn main() {} +> ``` r[frontmatter.position] Frontmatter may appear at the start of the file (after the optional [byte order mark]) or after a [shebang]. In either case, it may be preceded by [whitespace]. From 39faf0a151e48d51fd5b0e4bbf3fd7e86cdd50e9 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 4 Mar 2026 01:28:10 +0000 Subject: [PATCH 10/12] Rewrite frontmatter intro sentence The intro under `frontmatter.intro` said "an optional section for content intended for external tools without requiring these tools to have full knowledge of the Rust grammar." This was a negative construction (what frontmatter doesn't require) rather than a positive one (what it is and what it enables). In this commit, we rewrite the intro as "an optional section of metadata whose syntax allows external tools to read it without parsing Rust." This tells the reader three things in one sentence: what frontmatter is, who it's for, and the key design property. --- src/frontmatter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontmatter.md b/src/frontmatter.md index f32064ec39..8a555b1c9d 100644 --- a/src/frontmatter.md +++ b/src/frontmatter.md @@ -35,7 +35,7 @@ INFOSTRING -> (XID_Start | `_`) ( XID_Continue | `-` | `.` )* ``` r[frontmatter.intro] -Frontmatter is an optional section for content intended for external tools without requiring these tools to have full knowledge of the Rust grammar. +Frontmatter is an optional section of metadata whose syntax allows external tools to read it without parsing Rust. > [!EXAMPLE] > From a0727c546c02eba07f2c01b1e89944f4399ce8ad Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 4 Mar 2026 05:50:21 +0000 Subject: [PATCH 11/12] Note the UAX 31 provenance of `HORIZONTAL_WHITESPACE` For the `WHITESPACE` grammar rule, we cite `Pattern_White_Space`. For `HORIZONTAL_WHITESPACE`, we hadn't cited provenance. Let's do that. Horizontal whitespace, in a Unicode context, is defined by UAX 31, Section 4.1, which categorizes `Pattern_White_Space` into line endings, ignorable format controls, and horizontal space. The horizontal space category is exactly the two characters our grammar specifies. --- src/whitespace.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/whitespace.md b/src/whitespace.md index 25f33ee1c6..da0d8502b5 100644 --- a/src/whitespace.md +++ b/src/whitespace.md @@ -30,6 +30,9 @@ CR -> U+000D // Carriage return, `'\r'` r[lex.whitespace.intro] Whitespace is any non-empty string containing only characters that have the [`Pattern_White_Space`] Unicode property. +r[lex.whitespace.horizontal] +[HORIZONTAL_WHITESPACE] is the horizontal space subset of [`Pattern_White_Space`] as categorized by [UAX #31, Section 4.1][uax31-4.1]. + r[lex.whitespace.token-sep] Rust is a "free-form" language, meaning that all forms of whitespace serve only to separate _tokens_ in the grammar, and have no semantic significance. @@ -37,3 +40,4 @@ r[lex.whitespace.replacement] A Rust program has identical meaning if each whitespace element is replaced with any other legal whitespace element, such as a single space character. [`Pattern_White_Space`]: https://www.unicode.org/reports/tr31/ +[uax31-4.1]: https://www.unicode.org/reports/tr31/#Whitespace_and_Syntax From 526c143f64d835aae63575fa94f415bb672a9f3b Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 10 Mar 2026 22:40:10 +0000 Subject: [PATCH 12/12] Move frontmatter intro and example ahead of grammar Many of our existing chapters start directly with the grammar. We're shifting, however, toward leading with the introduction and with the introductory example. Let's do that for the frontmatter chapter. --- src/frontmatter.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/frontmatter.md b/src/frontmatter.md index 8a555b1c9d..3fe03294d8 100644 --- a/src/frontmatter.md +++ b/src/frontmatter.md @@ -1,6 +1,20 @@ r[frontmatter] # Frontmatter +r[frontmatter.intro] +Frontmatter is an optional section of metadata whose syntax allows external tools to read it without parsing Rust. + +> [!EXAMPLE] +> +> ```rust,ignore +> #!/bin/env cargo +> --- cargo +> package.edition = "2024" +> --- +> +> fn main() {} +> ``` + r[frontmatter.syntax] ```grammar,lexer @root FRONTMATTER -> @@ -34,20 +48,6 @@ MAYBE_INFOSTRING_OR_WS -> INFOSTRING -> (XID_Start | `_`) ( XID_Continue | `-` | `.` )* ``` -r[frontmatter.intro] -Frontmatter is an optional section of metadata whose syntax allows external tools to read it without parsing Rust. - -> [!EXAMPLE] -> -> ```rust,ignore -> #!/bin/env cargo -> --- cargo -> package.edition = "2024" -> --- -> -> fn main() {} -> ``` - r[frontmatter.position] Frontmatter may appear at the start of the file (after the optional [byte order mark]) or after a [shebang]. In either case, it may be preceded by [whitespace].