Skip to content
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

Add Identifier Syntax to Several Chapters #1597

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
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
27 changes: 26 additions & 1 deletion src/keywords.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Keywords

r[lex.keywords]

Rust divides keywords into three categories:

* [strict](#strict-keywords)
Expand All @@ -8,6 +10,9 @@ Rust divides keywords into three categories:

## Strict keywords

r[lex.keywords.strict]

r[lex.keywords.strict.intro]
These keywords can only be used in their correct contexts. They cannot
be used as the names of:

Expand All @@ -20,7 +25,8 @@ be used as the names of:
* [Macro placeholders]
* [Crates]

> **<sup>Lexer:</sup>**\
r[lex.keywords.strict.list]
> **<sup>Lexer:<sup>**\
> KW_AS : `as`\
> KW_BREAK : `break`\
> KW_CONST : `const`\
Expand Down Expand Up @@ -57,6 +63,7 @@ be used as the names of:
> KW_WHERE : `where`\
> KW_WHILE : `while`

r[lex.keywords.strict.edition2018]
The following keywords were added beginning in the 2018 edition.

> **<sup>Lexer 2018+</sup>**\
Expand All @@ -66,11 +73,15 @@ The following keywords were added beginning in the 2018 edition.

## Reserved keywords

r[lex.keywords.reserved]

r[lex.keywords.reserved.intro]
These keywords aren't used yet, but they are reserved for future use. They have
the same restrictions as strict keywords. The reasoning behind this is to make
current programs forward compatible with future versions of Rust by forbidding
them to use these keywords.

r[lex.keywords.reserved.list]
> **<sup>Lexer</sup>**\
> KW_ABSTRACT : `abstract`\
> KW_BECOME : `become`\
Expand All @@ -85,6 +96,7 @@ them to use these keywords.
> KW_VIRTUAL : `virtual`\
> KW_YIELD : `yield`

r[lex.keywords.reserved.edition2018]
The following keywords are reserved beginning in the 2018 edition.

> **<sup>Lexer 2018+</sup>**\
Expand All @@ -97,9 +109,13 @@ The following keywords are reserved beginning in the 2024 edition.

## Weak keywords

r[lex.keywords.weak]

r[lex.keywords.weak.intro]
These keywords have special meaning only in certain contexts. For example, it
is possible to declare a variable or method with the name `union`.

r[lex.keywords.weak.list]
> **<sup>Lexer</sup>**\
> KW_MACRO_RULES : `macro_rules`\
> KW_UNION : `union`\
Expand All @@ -110,24 +126,33 @@ is possible to declare a variable or method with the name `union`.
> **<sup>Lexer 2015</sup>**\
> KW_DYN : `dyn`

r[lex.keywords.weak.macro_rules]
* `macro_rules` is used to create custom [macros].

r[lex.keywords.weak.union]
* `union` is used to declare a [union] and is only a keyword when used in a
union declaration.

r[lex.keywords.weak.lifetime-static]
* `'static` is used for the static lifetime and cannot be used as a [generic
lifetime parameter] or [loop label]

```compile_fail
// error[E0262]: invalid lifetime parameter name: `'static`
fn invalid_lifetime_parameter<'static>(s: &'static str) -> &'static str { s }
```

r[lex.keywords.weak.dyn]
* In the 2015 edition, [`dyn`] is a keyword when used in a type position
followed by a path that does not start with `::` or `<`, a lifetime, a question mark, a `for`
keyword or an opening parenthesis.

Beginning in the 2018 edition, `dyn` has been promoted to a strict keyword.

r[lex.keywords.weak.safe]
* `safe` is used for functions and statics, which has meaning in [external blocks].

r[lex.keywords.weak.raw]
* `raw` is used for [raw borrow operators], and is only a keyword when matching a raw borrow operator form (such as `&raw const expr` or `&raw mut expr`).

[items]: items.md
Expand Down
48 changes: 42 additions & 6 deletions src/lifetime-elision.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
# Lifetime elision

r[lifetime-elision]

Rust has rules that allow lifetimes to be elided in various places where the
compiler can infer a sensible default choice.

## Lifetime elision in functions

r[lifetime-elision.function]

r[lifetime-elision.function.intro]
In order to make common patterns more ergonomic, lifetime arguments can be
*elided* in [function item], [function pointer], and [closure trait] signatures.
The following rules are used to infer lifetime parameters for elided lifetimes.
It is an error to elide lifetime parameters that cannot be inferred. The
placeholder lifetime, `'_`, can also be used to have a lifetime inferred in the
same way. For lifetimes in paths, using `'_` is preferred. Trait object
lifetimes follow different rules discussed

r[lifetime-elision.function.constraint]
It is an error to elide lifetime parameters that cannot be inferred.

r[lifetime-elision.function.explicit-placeholder]
The placeholder lifetime, `'_`, can also be used to have a lifetime inferred in the
same way. For lifetimes in paths, using `'_` is preferred.

r[lifetime-elision.function.only-functions]
Trait object lifetimes follow different rules discussed
[below](#default-trait-object-lifetimes).

r[lifetime-elision.function.implicit-lifetime-parameters]
* Each elided lifetime in the parameters becomes a distinct lifetime parameter.

r[lifetime-elision.function.output-lifetime]
* If there is exactly one lifetime used in the parameters (elided or not), that
lifetime is assigned to *all* elided output lifetimes.

r[lifetime-elision.function.reciever-lifetime]
In method signatures there is another rule

* If the receiver has type `&Self` or `&mut Self`, then the lifetime of that
Expand Down Expand Up @@ -78,27 +93,43 @@ fn frob(s: &str, t: &str) -> &str; // ILLEGAL

## Default trait object lifetimes

r[lifetime-elision.trait-object]

r[lifetime-elision.trait-object.intro]
The assumed lifetime of references held by a [trait object] is called its
_default object lifetime bound_. These were defined in [RFC 599] and amended in
[RFC 1156].

r[lifetime-elision.trait-object.explicit-bound]
These default object lifetime bounds are used instead of the lifetime parameter
elision rules defined above when the lifetime bound is omitted entirely. If
`'_` is used as the lifetime bound then the bound follows the usual elision
elision rules defined above when the lifetime bound is omitted entirely.

r[lifetime-elision.trait-object.explicit-placeholder]
If `'_` is used as the lifetime bound then the bound follows the usual elision
rules.

r[lifetime-elision.trait-object.containing-type]
If the trait object is used as a type argument of a generic type then the
containing type is first used to try to infer a bound.

r[lifetime-elision.trait-object.containing-type-unique]
* If there is a unique bound from the containing type then that is the default

r[lifetime-elision.trait-object.containing-type-explicit]
* If there is more than one bound from the containing type then an explicit
bound must be specified

r[lifetime-elision.trait-object.trait-bounds]
If neither of those rules apply, then the bounds on the trait are used:

r[lifetime-elision.trait-object.trait-unique]
* If the trait is defined with a single lifetime _bound_ then that bound is
used.

r[lifetime-elision.trait-object.static-lifetime]
* If `'static` is used for any lifetime bound then `'static` is used.

r[lifetime-elision.trait-object.default]
* If the trait has no lifetime bounds, then the lifetime is inferred in
expressions and is `'static` outside of expressions.

Expand Down Expand Up @@ -136,6 +167,7 @@ type T7<'a, 'b> = TwoBounds<'a, 'b, dyn Foo>;
// Error: the lifetime bound for this object type cannot be deduced from context
```

r[lifetime-elision.trait-object.innermost-type]
Note that the innermost object sets the bound, so `&'a Box<dyn Foo>` is still
`&'a Box<dyn Foo + 'static>`.

Expand All @@ -154,6 +186,9 @@ impl<'a> dyn Bar<'a> + 'a {}

## `'static` lifetime elision

r[lifetime-elision.item]

r[lifetime-elision.item.intro]
Both [constant] and [static] declarations of reference types have *implicit*
`'static` lifetimes unless an explicit lifetime is specified. As such, the
constant declarations involving `'static` above may be written without the
Expand All @@ -175,6 +210,7 @@ const BITS_N_STRINGS: BitsNStrings<'_> = BitsNStrings {
};
```

r[lifetime-elision.item.fn-types]
Note that if the `static` or `const` items include function or closure
references, which themselves include references, the compiler will first try
the standard elision rules. If it is unable to resolve the lifetimes by its
Expand Down
22 changes: 22 additions & 0 deletions src/macros.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
# Macros

r[macro]

r[macro.intro]
The functionality and syntax of Rust can be extended with custom definitions
called macros. They are given names, and invoked through a consistent
syntax: `some_extension!(...)`.

There are two ways to define new macros:

r[macro.rules]
* [Macros by Example] define new syntax in a higher-level, declarative way.

r[macro.proc]
* [Procedural Macros] define function-like macros, custom derives, and custom
attributes using functions that operate on input tokens.

## Macro Invocation

r[macro.invocation]

r[macro.invocation.syntax]
> **<sup>Syntax</sup>**\
> _MacroInvocation_ :\
> &nbsp;&nbsp; [_SimplePath_] `!` _DelimTokenTree_
Expand All @@ -29,17 +38,30 @@ There are two ways to define new macros:
> &nbsp;&nbsp; | [_SimplePath_] `!` `[` _TokenTree_<sup>\*</sup> `]` `;`\
> &nbsp;&nbsp; | [_SimplePath_] `!` `{` _TokenTree_<sup>\*</sup> `}`

r[macro.invocation.intro]
A macro invocation expands a macro at compile time and replaces the
invocation with the result of the macro. Macros may be invoked in the
following situations:

r[macro.invocation.expr]
* [Expressions] and [statements]

r[macro.invocation.pattern]
* [Patterns]

r[macro.invocation.type]
* [Types]

r[macro.invocation.item]
* [Items] including [associated items]

r[macro.invocation.nested]
* [`macro_rules`] transcribers

r[macro.invocation.extern]
* [External blocks]

r[macro.invocation.item-statement]
When used as an item or a statement, the _MacroInvocationSemi_ form is used
where a semicolon is required at the end when not using curly braces.
[Visibility qualifiers] are never allowed before a macro invocation or
Expand Down
4 changes: 4 additions & 0 deletions src/memory-allocation-and-lifetime.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Memory allocation and lifetime

r[alloc]

r[alloc.static]
The _items_ of a program are those functions, modules, and types that have their
value calculated at compile-time and stored uniquely in the memory image of the
rust process. Items are neither dynamically allocated nor freed.

r[alloc.dynamic]
The _heap_ is a general term that describes boxes. The lifetime of an
allocation in the heap depends on the lifetime of the box values pointing to
it. Since box values may themselves be passed in and out of frames, or stored
Expand Down
Loading
Loading