Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/items/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Function ->
FunctionReturnType? WhereClause?
( BlockExpression | `;` )

FunctionQualifiers -> `const`? `async`?[^async-edition] ItemSafety?[^extern-qualifiers] (`extern` Abi?)?
FunctionQualifiers -> `const`? `async`?[^async-edition] Safety?[^extern-qualifiers] (`extern` Abi?)?

ItemSafety -> `safe`[^extern-safe] | `unsafe`
Safety -> `safe`[^safe-semantics] | `unsafe`

Abi -> STRING_LITERAL | RAW_STRING_LITERAL

Expand All @@ -34,12 +34,12 @@ FunctionReturnType -> `->` Type

[^async-edition]: The `async` qualifier is not allowed in the 2015 edition.

[^extern-safe]: The `safe` function qualifier is only allowed semantically within `extern` blocks.

[^extern-qualifiers]: *Relevant to editions earlier than Rust 2024*: Within `extern` blocks, the `safe` or `unsafe` function qualifier is only allowed when the `extern` is qualified as `unsafe`.
[^extern-qualifiers]: The `safe` or `unsafe` qualifiers are only allowed semantically within `extern` blocks. *Relevant to editions earlier than Rust 2024*: More specifically within `extern` blocks that are qualified as `unsafe`.

[^fn-param-2015]: Function parameters with only a type are only allowed in an associated function of a [trait item] in the 2015 edition.

[^safe-semantics]: The `safe` qualifier is only allowed semantically on functions and function pointer types within `extern` blocks.
Copy link
Copy Markdown
Member Author

@fmease fmease Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[^safe-semantics]: The `safe` qualifier is only allowed semantically on functions and function pointer types within `extern` blocks.
[^safe-semantics]: The `safe` qualifier is only allowed semantically on functions within `extern` blocks.

oops

View changes since the review


r[items.fn.intro]
A _function_ consists of a [block] (that's the _body_ of the function), along with a name, a set of parameters, and an output type. Other than a name, all these are optional.

Expand Down
4 changes: 2 additions & 2 deletions src/items/static-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ r[items.static]
r[items.static.syntax]
```grammar,items
StaticItem ->
ItemSafety?[^extern-safety] `static` `mut`? IDENTIFIER `:` Type ( `=` Expression )? `;`
Safety?[^extern-qualifiers] `static` `mut`? IDENTIFIER `:` Type ( `=` Expression )? `;`
```

[^extern-safety]: The `safe` and `unsafe` function qualifiers are only allowed semantically within `extern` blocks.
[^extern-qualifiers]: The `safe` and `unsafe` qualifiers are only allowed semantically within `extern` blocks. *Relevant to editions earlier than Rust 2024*: More specifically within `extern` blocks that are qualified as `unsafe`.

r[items.static.intro]
A *static item* is similar to a [constant], except that it represents an allocation in the program that is initialized with the initializer expression. All references and raw pointers to the static refer to the same allocation.
Expand Down
16 changes: 7 additions & 9 deletions src/types/function-pointer.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,21 @@ r[type.fn-pointer.syntax]
```grammar,types
BareFunctionType ->
ForLifetimes? FunctionTypeQualifiers `fn`
`(` FunctionParametersMaybeNamedVariadic? `)` BareFunctionReturnType?
`(` MaybeNamedFunctionParameters? `)` BareFunctionReturnType?

FunctionTypeQualifiers -> `unsafe`? (`extern` Abi?)?
FunctionTypeQualifiers -> Safety? (`extern` Abi?)?

BareFunctionReturnType -> `->` TypeNoBounds

FunctionParametersMaybeNamedVariadic ->
MaybeNamedFunctionParameters | MaybeNamedFunctionParametersVariadic

MaybeNamedFunctionParameters ->
MaybeNamedParam ( `,` MaybeNamedParam )* `,`?
SelfParam `,`?
| (SelfParam `,`)? MaybeNamedParam ( `,` MaybeNamedParam )* `,`?

MaybeNamedParam ->
OuterAttribute* ( ( IDENTIFIER | `_` ) `:` )? Type
OuterAttribute* ( MaybeNamedPattern `:` )? ( Type | `...` )

MaybeNamedFunctionParametersVariadic ->
( MaybeNamedParam `,` )* MaybeNamedParam `,` OuterAttribute* `...`
MaybeNamedPattern ->
`mut`? IDENTIFIER | ( `&` | `&&` )? ( `_` | `false` | `true` )
Copy link
Copy Markdown
Member Author

@fmease fmease Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, indeed, that's the grammar! It's a tiny subset of patterns.

Note that this subgrammar is also used for associated functions in traits in Rust 2015. I didn't know how I am meant to branch on editions, so I didn't update the corresponding function item grammar that currently only has FunctionParam -> … Type[^fn-param-2015] … which is not sufficient strictly speaking.

I guess I could do sth. akin to "ModernGrammar[^1] | LegacyGrammar[^2] // [^1]: Rust 2018–2024 // [^2]: Rust 2015 only" (pseudo). Let me know what you think.

View changes since the review

Copy link
Copy Markdown
Member Author

@fmease fmease Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Note somewhere (maybe in a footnote that semantically only identifiers and underscores are valid)

View changes since the review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look quite right. My understanding is that this logic comes from is_named_param.

I think it would look something closer to:

Suggested change
`mut`? IDENTIFIER | ( `&` | `&&` )? ( `_` | `false` | `true` )
((`mut`? | `&` | `&&`)? IDENTIFIER) | ((`&` | `&&`)? (`_` | `false` | `true`))

because ident can be preceded by & or &&.

However, this seems to be getting close to the territory of unintentional behavior. I'm wondering if this really is a bug in the compiler, and the grammar should be something else.

```

r[type.fn-pointer.intro]
Expand Down
Loading