Skip to content

Simplify rules for GenericArgs nonterminal and other small improvements and fixes #805

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
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
5 changes: 2 additions & 3 deletions src/expressions/closure-expr.md
Original file line number Diff line number Diff line change
@@ -4,10 +4,10 @@
> _ClosureExpression_ :\
> &nbsp;&nbsp; `move`<sup>?</sup>\
> &nbsp;&nbsp; ( `||` | `|` _ClosureParameters_<sup>?</sup> `|` )\
> &nbsp;&nbsp; ([_Expression_] | `->` [_TypeNoBounds_]&nbsp;[_BlockExpression_])
> &nbsp;&nbsp; ( [_Expression_] | `->` [_Type_]&nbsp;[_BlockExpression_] )
>
> _ClosureParameters_ :\
> &nbsp;&nbsp; _ClosureParam_ (`,` _ClosureParam_)<sup>\*</sup> `,`<sup>?</sup>
> &nbsp;&nbsp; _ClosureParam_ ( `,` _ClosureParam_ )<sup>\*</sup> `,`<sup>?</sup>
>
> _ClosureParam_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_Pattern_]&nbsp;( `:` [_Type_] )<sup>?</sup>
@@ -79,7 +79,6 @@ Attributes on closure parameters follow the same rules and restrictions as

[_Expression_]: ../expressions.md
[_BlockExpression_]: block-expr.md
[_TypeNoBounds_]: ../types.md#type-expressions
[_Pattern_]: ../patterns.md
[_Type_]: ../types.md#type-expressions
[`let` binding]: ../statements.md#let-statements
18 changes: 7 additions & 11 deletions src/items/generics.md
Original file line number Diff line number Diff line change
@@ -2,20 +2,16 @@

> **<sup>Syntax</sup>**\
> _Generics_ :\
> &nbsp;&nbsp; `<` _GenericParams_ `>`
> &nbsp;&nbsp; `<` _GenericParams_<sup>?</sup> `>`
>
> _GenericParams_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; _LifetimeParams_\
> &nbsp;&nbsp; | ( _LifetimeParam_ `,` )<sup>\*</sup> _TypeParams_
> &nbsp;&nbsp; _GenericParam_ ( `,` _GenericParam_ )<sup>\*</sup> `,`<sup>?</sup>
>
> _LifetimeParams_ :\
> &nbsp;&nbsp; ( _LifetimeParam_ `,` )<sup>\*</sup> _LifetimeParam_<sup>?</sup>
> _GenericParam_ :\
> &nbsp;&nbsp; _LifetimeParam_ | _TypeParam_
>
> _LifetimeParam_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>?</sup> [LIFETIME_OR_LABEL]&nbsp;( `:` [_LifetimeBounds_] )<sup>?</sup>
>
> _TypeParams_:\
> &nbsp;&nbsp; ( _TypeParam_ `,` )<sup>\*</sup> _TypeParam_<sup>?</sup>
> &nbsp;&nbsp; [_OuterAttribute_]<sup>?</sup> [LIFETIME_OR_LABEL]&nbsp;( `:` [_LifetimeBounds_]<sup>?</sup> )<sup>?</sup>
>
> _TypeParam_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>?</sup> [IDENTIFIER] ( `:` [_TypeParamBounds_]<sup>?</sup> )<sup>?</sup> ( `=` [_Type_] )<sup>?</sup>
@@ -49,13 +45,13 @@ referred to with path syntax.
> &nbsp;&nbsp; | _TypeBoundWhereClauseItem_
>
> _LifetimeWhereClauseItem_ :\
> &nbsp;&nbsp; [_Lifetime_] `:` [_LifetimeBounds_]
> &nbsp;&nbsp; [_Lifetime_] `:` [_LifetimeBounds_]<sup>?</sup>
>
> _TypeBoundWhereClauseItem_ :\
> &nbsp;&nbsp; _ForLifetimes_<sup>?</sup> [_Type_] `:` [_TypeParamBounds_]<sup>?</sup>
>
> _ForLifetimes_ :\
> &nbsp;&nbsp; `for` `<` [_LifetimeParams_](#type-and-lifetime-parameters) `>`
> &nbsp;&nbsp; `for` `<` [_LifetimeParams_](#type-and-lifetime-parameters)<sup>?</sup> `>`
Copy link
Contributor

Choose a reason for hiding this comment

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

You've removed LifetimeParams, so either this will need to be updated, or LifetimeParams will need to be added back.

Copy link
Member Author

@steffahn steffahn Apr 25, 2020

Choose a reason for hiding this comment

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

Ah... missed that – good thing I changed them both in an earlier commit in a way that required updating all uses and hence the uses pop out in the diff.

*Where clauses* provide another way to specify bounds on type and lifetime
parameters as well as a way to specify bounds on types that aren't type
4 changes: 2 additions & 2 deletions src/items/use-declarations.md
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@
> &nbsp;&nbsp; `use` _UseTree_ `;`
>
> _UseTree_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; ([_SimplePath_]<sup>?</sup> `::`)<sup>?</sup> `*`\
> &nbsp;&nbsp; | ([_SimplePath_]<sup>?</sup> `::`)<sup>?</sup> `{` (_UseTree_ ( `,` _UseTree_ )<sup>\*</sup> `,`<sup>?</sup>)<sup>?</sup> `}`\
> &nbsp;&nbsp; &nbsp;&nbsp; ( [_SimplePath_]<sup>?</sup> `::` )<sup>?</sup> `*`\
> &nbsp;&nbsp; | ( [_SimplePath_]<sup>?</sup> `::` )<sup>?</sup> `{` ( _UseTree_ ( `,` _UseTree_ )<sup>\*</sup> `,`<sup>?</sup> )<sup>?</sup> `}`\
> &nbsp;&nbsp; | [_SimplePath_]&nbsp;( `as` ( [IDENTIFIER] | `_` ) )<sup>?</sup>
A _use declaration_ creates one or more local name bindings synonymous with
58 changes: 27 additions & 31 deletions src/paths.md
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ x::y::z;

> **<sup>Syntax</sup>**\
> _SimplePath_ :\
> &nbsp;&nbsp; `::`<sup>?</sup> _SimplePathSegment_ (`::` _SimplePathSegment_)<sup>\*</sup>
> &nbsp;&nbsp; `::`<sup>?</sup> _SimplePathSegment_ ( `::` _SimplePathSegment_ )<sup>\*</sup>
>
> _SimplePathSegment_ :\
> &nbsp;&nbsp; [IDENTIFIER] | `super` | `self` | `crate` | `$crate`
@@ -40,42 +40,34 @@ mod m {

> **<sup>Syntax</sup>**\
> _PathInExpression_ :\
> &nbsp;&nbsp; `::`<sup>?</sup> _PathExprSegment_ (`::` _PathExprSegment_)<sup>\*</sup>
> &nbsp;&nbsp; `::`<sup>?</sup> _PathExprSegment_ ( `::` _PathExprSegment_ )<sup>\*</sup>
>
> _PathExprSegment_ :\
> &nbsp;&nbsp; _PathIdentSegment_ (`::` _GenericArgs_)<sup>?</sup>
> &nbsp;&nbsp; _PathIdentSegment_ ( `::` `<` _GenericArguments_<sup>?</sup> `>` )<sup>?</sup>
>
> _PathIdentSegment_ :\
> &nbsp;&nbsp; [IDENTIFIER] | `super` | `self` | `Self` | `crate` | `$crate`
>
> _GenericArgs_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; `<` `>`\
> &nbsp;&nbsp; | `<` _GenericArgsLifetimes_ `,`<sup>?</sup> `>`\
> &nbsp;&nbsp; | `<` _GenericArgsTypes_ `,`<sup>?</sup> `>`\
> &nbsp;&nbsp; | `<` _GenericArgsBindings_ `,`<sup>?</sup> `>`\
> &nbsp;&nbsp; | `<` _GenericArgsTypes_ `,` _GenericArgsBindings_ `,`<sup>?</sup> `>`\
> &nbsp;&nbsp; | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,`<sup>?</sup> `>`\
> &nbsp;&nbsp; | `<` _GenericArgsLifetimes_ `,` _GenericArgsBindings_ `,`<sup>?</sup> `>`\
> &nbsp;&nbsp; | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,` _GenericArgsBindings_ `,`<sup>?</sup> `>`
> _GenericArguments_ :\
> &nbsp;&nbsp; _GenericArgument_ ( `,` _GenericArgument_ )<sup>\*</sup> `,`<sup>?</sup>
>
> _GenericArgsLifetimes_ :\
> &nbsp;&nbsp; [_Lifetime_] (`,` [_Lifetime_])<sup>\*</sup>
>
> _GenericArgsTypes_ :\
> &nbsp;&nbsp; [_Type_] (`,` [_Type_])<sup>\*</sup>
>
> _GenericArgsBindings_ :\
> &nbsp;&nbsp; _GenericArgsBinding_ (`,` _GenericArgsBinding_)<sup>\*</sup>
>
> _GenericArgsBinding_ :\
> &nbsp;&nbsp; [IDENTIFIER] `=` [_Type_]
> _GenericArgument_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [_Lifetime_]\
> &nbsp;&nbsp; | [_Type_]\
> &nbsp;&nbsp; | [IDENTIFIER] `=` [_Type_]
Paths in expressions allow for paths with generic arguments to be specified. They are
used in various places in [expressions] and [patterns].

The `::` token is required before the opening `<` for generic arguments to avoid
ambiguity with the less-than operator. This is colloquially known as "turbofish" syntax.

Generic arguments are passed in the order that they're declared in. In particular,
lifetime arguments must come before type arguments. The last kind of argument,
`Ident = Type`, is for specifying [associated types] in [trait bounds].
These arguments are not positional (i.e. their order does not matter), and they
must come after all the other (positional) arguments.
Comment on lines +65 to +69
Copy link
Contributor

Choose a reason for hiding this comment

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

The first sentence seems to be immediately contradicted by the statement that the order of bindings doesn't matter. Perhaps it would help to explicitly name the 3 argument kinds, specify the order they must appear in relation to each other, and then delve into the specifics of how type bindings work?

I'd also lean towards retaining the named nonterminals in the grammar, so there is something to refer to (like GenericArgsBinding).

I'm also a little amused about the idea of specifying how the order of arguments correlates to the parameters. Most specs I've read just ignore this, presumably assuming everyone knows function arguments are passed in the given order to the corresponding parameters.

Copy link
Member Author

Choose a reason for hiding this comment

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

The main point was that if you already know that the argument order matches the declaration, then the fact that lifetime argument come before type arguments directly follows from the fact that function, trait and method declarations must put lifetime arguments first.

I’ll try to get rid of the contradictory statements, and reintroducing (at least some of) the names seems like a very good idea to make things clearer.

Copy link
Member Author

Choose a reason for hiding this comment

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

then the fact that lifetime argument come before type arguments directly follows from […]

The compiler seems to (maybe) apply the same logic (note how it only complains about “associated type bindings” coming before “generic parameters” without knowing the details Foo).

Well, it can also generate weird messages if you do let it know of a Foo.


```rust
(0..10).collect::<Vec<_>>();
Vec::<u8>::with_capacity(1024);
@@ -85,13 +77,13 @@ Vec::<u8>::with_capacity(1024);

> **<sup>Syntax</sup>**\
> _QualifiedPathInExpression_ :\
> &nbsp;&nbsp; _QualifiedPathType_ (`::` _PathExprSegment_)<sup>+</sup>
> &nbsp;&nbsp; _QualifiedPathType_ ( `::` _PathExprSegment_ )<sup>+</sup>
>
> _QualifiedPathType_ :\
> &nbsp;&nbsp; `<` [_Type_] (`as` _TypePath_)? `>`
> &nbsp;&nbsp; `<` [_Type_] ( `as` _TypePath_ )<sup>?</sup> `>`
>
> _QualifiedPathInType_ :\
> &nbsp;&nbsp; _QualifiedPathType_ (`::` _TypePathSegment_)<sup>+</sup>
> &nbsp;&nbsp; _QualifiedPathType_ ( `::` _TypePathSegment_ )<sup>+</sup>
Fully qualified paths allow for disambiguating the path for [trait implementations] and
for specifying [canonical paths](#canonical-paths). When used in a type specification, it
@@ -119,13 +111,14 @@ S::f(); // Calls the inherent impl.

> **<sup>Syntax</sup>**\
> _TypePath_ :\
> &nbsp;&nbsp; `::`<sup>?</sup> _TypePathSegment_ (`::` _TypePathSegment_)<sup>\*</sup>
> &nbsp;&nbsp; `::`<sup>?</sup> _TypePathSegment_ ( `::` _TypePathSegment_ )<sup>\*</sup>
>
> _TypePathSegment_ :\
> &nbsp;&nbsp; _PathIdentSegment_ `::`<sup>?</sup> ([_GenericArgs_] | _TypePathFn_)<sup>?</sup>
> &nbsp;&nbsp; _PathIdentSegment_ ( `::`<sup>?</sup> _TypePathArguments_ )<sup>?</sup>
>
> _TypePathFn_ :\
> `(` _TypePathFnInputs_<sup>?</sup> `)` (`->` [_Type_])<sup>?</sup>
> _TypePathArguments_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; `<` [_GenericArguments_]<sup>?</sup> `>`\
> &nbsp;&nbsp; | `(` _TypePathFnInputs_<sup>?</sup> `)` [_FunctionReturnType_]<sup>?</sup>
>
> _TypePathFnInputs_ :\
> [_Type_] (`,` [_Type_])<sup>\*</sup> `,`<sup>?</sup>
@@ -364,9 +357,10 @@ mod without { // ::without
# fn main() {}
```

[_GenericArgs_]: #paths-in-expressions
[_GenericArguments_]: #paths-in-expressions
[_Lifetime_]: trait-bounds.md
[_Type_]: types.md#type-expressions
[_FunctionReturnType_]: items/functions.md
[item]: items.md
[variable]: variables.md
[implementations]: items/implementations.md
@@ -381,3 +375,5 @@ mod without { // ::without
[trait implementations]: items/implementations.md#trait-implementations
[traits]: items/traits.md
[visibility]: visibility-and-privacy.md
[associated types]: items/associated-items.md#associated-types
[trait bounds]: trait-bounds.md
57 changes: 29 additions & 28 deletions src/tokens.md
Original file line number Diff line number Diff line change
@@ -28,14 +28,14 @@ evaluated (primarily) at compile time.

#### Characters and strings

| | Example | `#` sets | Characters | Escapes |
| | Example | `#` sets | Characters | Escapes |
|----------------------------------------------|-----------------|-------------|-------------|---------------------|
| [Character](#character-literals) | `'H'` | 0 | All Unicode | [Quote](#quote-escapes) & [ASCII](#ascii-escapes) & [Unicode](#unicode-escapes) |
| [String](#string-literals) | `"hello"` | 0 | All Unicode | [Quote](#quote-escapes) & [ASCII](#ascii-escapes) & [Unicode](#unicode-escapes) |
| [Raw string](#raw-string-literals) | `r#"hello"#` | 0 or more\* | All Unicode | `N/A` |
| [Byte](#byte-literals) | `b'H'` | 0 | All ASCII | [Quote](#quote-escapes) & [Byte](#byte-escapes) |
| [Byte string](#byte-string-literals) | `b"hello"` | 0 | All ASCII | [Quote](#quote-escapes) & [Byte](#byte-escapes) |
| [Raw byte string](#raw-byte-string-literals) | `br#"hello"#` | 0 or more\* | All ASCII | `N/A` |
| [Raw string](#raw-string-literals) | `r#"hello"#` | 0 or more\* | All Unicode | `N/A` |
| [Byte](#byte-literals) | `b'H'` | 0 | All ASCII | [Quote](#quote-escapes) & [Byte](#byte-escapes) |
| [Byte string](#byte-string-literals) | `b"hello"` | 0 | All ASCII | [Quote](#quote-escapes) & [Byte](#byte-escapes) |
| [Raw byte string](#raw-byte-string-literals) | `br#"hello"#` | 0 or more\* | All ASCII | `N/A` |

\* The number of `#`s on each side of the same literal must be equivalent

@@ -121,11 +121,11 @@ and numeric literal tokens are accepted only with suffixes from the list below.
> &nbsp;&nbsp; `\'` | `\"`
>
> ASCII_ESCAPE :\
> &nbsp;&nbsp; &nbsp;&nbsp; `\x` OCT_DIGIT HEX_DIGIT\
> &nbsp;&nbsp; &nbsp;&nbsp; `\x` [OCT_DIGIT](#integer-literals) [HEX_DIGIT](#integer-literals)\
> &nbsp;&nbsp; | `\n` | `\r` | `\t` | `\\` | `\0`
>
> UNICODE_ESCAPE :\
> &nbsp;&nbsp; `\u{` ( HEX_DIGIT `_`<sup>\*</sup> )<sup>1..6</sup> `}`
> &nbsp;&nbsp; `\u{` ( [HEX_DIGIT](#integer-literals) `_`<sup>\*</sup> )<sup>1..6</sup> `}`
A _character literal_ is a single Unicode character enclosed within two
`U+0027` (single-quote) characters, with the exception of `U+0027` itself,
@@ -136,10 +136,10 @@ which must be _escaped_ by a preceding `U+005C` character (`\`).
> **<sup>Lexer</sup>**\
> STRING_LITERAL :\
> &nbsp;&nbsp; `"` (\
> &nbsp;&nbsp; &nbsp;&nbsp; ~[`"` `\` _IsolatedCR_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | QUOTE_ESCAPE\
> &nbsp;&nbsp; &nbsp;&nbsp; | ASCII_ESCAPE\
> &nbsp;&nbsp; &nbsp;&nbsp; | UNICODE_ESCAPE\
> &nbsp;&nbsp; &nbsp;&nbsp; ~[`"` `\` [_IsolatedCR_][comments]]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [QUOTE_ESCAPE](#character-literals)\
> &nbsp;&nbsp; &nbsp;&nbsp; | [ASCII_ESCAPE](#character-literals)\
> &nbsp;&nbsp; &nbsp;&nbsp; | [UNICODE_ESCAPE](#character-literals)\
> &nbsp;&nbsp; &nbsp;&nbsp; | STRING_CONTINUE\
> &nbsp;&nbsp; )<sup>\*</sup> `"`
>
@@ -194,7 +194,7 @@ following forms:
> &nbsp;&nbsp; `r` RAW_STRING_CONTENT
>
> RAW_STRING_CONTENT :\
> &nbsp;&nbsp; &nbsp;&nbsp; `"` ( ~ _IsolatedCR_ )<sup>* (non-greedy)</sup> `"`\
> &nbsp;&nbsp; &nbsp;&nbsp; `"` ( ~ [_IsolatedCR_][comments] )<sup>* (non-greedy)</sup> `"`\
> &nbsp;&nbsp; | `#` RAW_STRING_CONTENT `#`
Raw string literals do not process any escapes. They start with the character
@@ -234,7 +234,7 @@ r##"foo #"# bar"##; // foo #"# bar
> &nbsp;&nbsp; _any ASCII (i.e. 0x00 to 0x7F), except_ `'`, `\`, \\n, \\r or \\t
>
> BYTE_ESCAPE :\
> &nbsp;&nbsp; &nbsp;&nbsp; `\x` HEX_DIGIT HEX_DIGIT\
> &nbsp;&nbsp; &nbsp;&nbsp; `\x` [HEX_DIGIT](#integer-literals) [HEX_DIGIT](#integer-literals)\
> &nbsp;&nbsp; | `\n` | `\r` | `\t` | `\\` | `\0`
A _byte literal_ is a single ASCII character (in the `U+0000` to `U+007F`
@@ -248,10 +248,10 @@ _number literal_.

> **<sup>Lexer</sup>**\
> BYTE_STRING_LITERAL :\
> &nbsp;&nbsp; `b"` ( ASCII_FOR_STRING | BYTE_ESCAPE | STRING_CONTINUE )<sup>\*</sup> `"`
> &nbsp;&nbsp; `b"` ( ASCII_FOR_STRING | [BYTE_ESCAPE](#byte-literals) | [STRING_CONTINUE](#string-literals) )<sup>\*</sup> `"`
>
> ASCII_FOR_STRING :\
> &nbsp;&nbsp; _any ASCII (i.e 0x00 to 0x7F), except_ `"`, `\` _and IsolatedCR_
> &nbsp;&nbsp; _any ASCII (i.e 0x00 to 0x7F), except_ `"`, `\` _and_ [_IsolatedCR_][comments]
A non-raw _byte string literal_ is a sequence of ASCII characters and _escapes_,
preceded by the characters `U+0062` (`b`) and `U+0022` (double-quote), and
@@ -283,7 +283,7 @@ following forms:
>
> RAW_BYTE_STRING_CONTENT :\
> &nbsp;&nbsp; &nbsp;&nbsp; `"` ASCII<sup>* (non-greedy)</sup> `"`\
> &nbsp;&nbsp; | `#` RAW_STRING_CONTENT `#`
> &nbsp;&nbsp; | `#` [RAW_STRING_CONTENT](#raw-string-literals) `#`
>
> ASCII :\
> &nbsp;&nbsp; _any ASCII (i.e. 0x00 to 0x7F)_
@@ -327,20 +327,20 @@ literal_. The grammar for recognizing the two kinds of literals is mixed.
> INTEGER_SUFFIX<sup>?</sup>
>
> DEC_LITERAL :\
> &nbsp;&nbsp; DEC_DIGIT (DEC_DIGIT|`_`)<sup>\*</sup>
> &nbsp;&nbsp; DEC_DIGIT ( DEC_DIGIT | `_` )<sup>\*</sup>
>
> TUPLE_INDEX :\
> &nbsp;&nbsp; &nbsp;&nbsp; `0`
> &nbsp;&nbsp; &nbsp;&nbsp; `0`\
> &nbsp;&nbsp; | NON_ZERO_DEC_DIGIT DEC_DIGIT<sup>\*</sup>
>
> BIN_LITERAL :\
> &nbsp;&nbsp; `0b` (BIN_DIGIT|`_`)<sup>\*</sup> BIN_DIGIT (BIN_DIGIT|`_`)<sup>\*</sup>
> &nbsp;&nbsp; `0b` ( BIN_DIGIT | `_` )<sup>\*</sup> BIN_DIGIT ( BIN_DIGIT | `_` )<sup>\*</sup>
>
> OCT_LITERAL :\
> &nbsp;&nbsp; `0o` (OCT_DIGIT|`_`)<sup>\*</sup> OCT_DIGIT (OCT_DIGIT|`_`)<sup>\*</sup>
> &nbsp;&nbsp; `0o` ( OCT_DIGIT | `_` )<sup>\*</sup> OCT_DIGIT ( OCT_DIGIT | `_` )<sup>\*</sup>
>
> HEX_LITERAL :\
> &nbsp;&nbsp; `0x` (HEX_DIGIT|`_`)<sup>\*</sup> HEX_DIGIT (HEX_DIGIT|`_`)<sup>\*</sup>
> &nbsp;&nbsp; `0x` ( HEX_DIGIT | `_` )<sup>\*</sup> HEX_DIGIT ( HEX_DIGIT | `_` )<sup>\*</sup>
>
> BIN_DIGIT : [`0`-`1`]
>
@@ -446,16 +446,16 @@ a single integer literal.

> **<sup>Lexer</sup>**\
> FLOAT_LITERAL :\
> &nbsp;&nbsp; &nbsp;&nbsp; DEC_LITERAL `.`
> _(not immediately followed by `.`, `_` or an [identifier]_)\
> &nbsp;&nbsp; | DEC_LITERAL FLOAT_EXPONENT\
> &nbsp;&nbsp; | DEC_LITERAL `.` DEC_LITERAL FLOAT_EXPONENT<sup>?</sup>\
> &nbsp;&nbsp; | DEC_LITERAL (`.` DEC_LITERAL)<sup>?</sup>
> &nbsp;&nbsp; &nbsp;&nbsp; [DEC_LITERAL](#integer-literals) `.`
> _(not immediately followed by `.`, `_` or an [identifier])_\
> &nbsp;&nbsp; | [DEC_LITERAL](#integer-literals) FLOAT_EXPONENT\
> &nbsp;&nbsp; | [DEC_LITERAL](#integer-literals) `.` [DEC_LITERAL](#integer-literals) FLOAT_EXPONENT<sup>?</sup>\
> &nbsp;&nbsp; | [DEC_LITERAL](#integer-literals) ( `.` [DEC_LITERAL](#integer-literals) )<sup>?</sup>
> FLOAT_EXPONENT<sup>?</sup> FLOAT_SUFFIX
>
> FLOAT_EXPONENT :\
> &nbsp;&nbsp; (`e`|`E`) (`+`|`-`)?
> (DEC_DIGIT|`_`)<sup>\*</sup> DEC_DIGIT (DEC_DIGIT|`_`)<sup>\*</sup>
> &nbsp;&nbsp; ( `e` | `E` ) ( `+` | `-` )<sup>?</sup>
> ( [DEC_DIGIT](#integer-literals) | `_` )<sup>\*</sup> [DEC_DIGIT](#integer-literals) ( [DEC_DIGIT](#integer-literals) | `_` )<sup>\*</sup>
>
> FLOAT_SUFFIX :\
> &nbsp;&nbsp; `f32` | `f64`
@@ -605,6 +605,7 @@ them are referred to as "token trees" in [macros]. The three types of brackets
[attributes]: attributes.md
[borrow]: expressions/operator-expr.md#borrow-operators
[closures]: expressions/closure-expr.md
[comments]: comments.md
[comparison]: expressions/operator-expr.md#comparison-operators
[compound]: expressions/operator-expr.md#compound-assignment-expressions
[dereference]: expressions/operator-expr.md#the-dereference-operator
7 changes: 4 additions & 3 deletions src/trait-bounds.md
Original file line number Diff line number Diff line change
@@ -9,12 +9,12 @@
>
> _TraitBound_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; `?`<sup>?</sup>
> [_ForLifetimes_](#higher-ranked-trait-bounds)<sup>?</sup> [_TypePath_]\
> [_ForLifetimes_]<sup>?</sup> [_TypePath_]\
> &nbsp;&nbsp; | `(` `?`<sup>?</sup>
> [_ForLifetimes_](#higher-ranked-trait-bounds)<sup>?</sup> [_TypePath_] `)`
> [_ForLifetimes_]<sup>?</sup> [_TypePath_] `)`
>
> _LifetimeBounds_ :\
> &nbsp;&nbsp; ( _Lifetime_ `+` )<sup>\*</sup> _Lifetime_<sup>?</sup>
> &nbsp;&nbsp; _Lifetime_ ( `+` _Lifetime_ )<sup>\*</sup> `+`<sup>?</sup>
>
> _Lifetime_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [LIFETIME_OR_LABEL]\
@@ -139,6 +139,7 @@ fn call_on_ref_zero<F>(f: F) where F: for<'a> Fn(&'a i32) {
[LIFETIME_OR_LABEL]: tokens.md#lifetimes-and-loop-labels
[_TypePath_]: paths.md#paths-in-types
[`Sized`]: special-types-and-traits.md#sized
[_ForLifetimes_]: items/generics.html#where-clauses

[associated types]: items/associated-items.md#associated-types
[supertraits]: items/traits.md#supertraits
2 changes: 1 addition & 1 deletion src/types.md
Original file line number Diff line number Diff line change
@@ -129,7 +129,7 @@ let a: List<i32> = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil))));
[_ParenthesizedType_]: types.md#parenthesized-types
[_QualifiedPathInType_]: paths.md#qualified-paths
[_RawPointerType_]: types/pointer.md#raw-pointers-const-and-mut
[_ReferenceType_]: types/pointer.md#shared-references-
[_ReferenceType_]: types/pointer.md#references--and-mut
[_SliceType_]: types/slice.md
[_TraitObjectTypeOneBound_]: types/trait-object.md
[_TraitObjectType_]: types/trait-object.md