Auto merge of #24759 - Manishearth:rollup2, r=Manishearth
r? @Manishearth
This commit is contained in:
commit
9d439b4177
@ -29,7 +29,7 @@ You may also be interested in the [grammar].
|
|||||||
|
|
||||||
# Notation
|
# Notation
|
||||||
|
|
||||||
Rust's grammar is defined over Unicode codepoints, each conventionally denoted
|
Rust's grammar is defined over Unicode code points, each conventionally denoted
|
||||||
`U+XXXX`, for 4 or more hexadecimal digits `X`. _Most_ of Rust's grammar is
|
`U+XXXX`, for 4 or more hexadecimal digits `X`. _Most_ of Rust's grammar is
|
||||||
confined to the ASCII range of Unicode, and is described in this document by a
|
confined to the ASCII range of Unicode, and is described in this document by a
|
||||||
dialect of Extended Backus-Naur Form (EBNF), specifically a dialect of EBNF
|
dialect of Extended Backus-Naur Form (EBNF), specifically a dialect of EBNF
|
||||||
@ -53,7 +53,7 @@ Where:
|
|||||||
- Square brackets are used to group rules.
|
- Square brackets are used to group rules.
|
||||||
- `LITERAL` is a single printable ASCII character, or an escaped hexadecimal
|
- `LITERAL` is a single printable ASCII character, or an escaped hexadecimal
|
||||||
ASCII code of the form `\xQQ`, in single quotes, denoting the corresponding
|
ASCII code of the form `\xQQ`, in single quotes, denoting the corresponding
|
||||||
Unicode codepoint `U+00QQ`.
|
Unicode code point `U+00QQ`.
|
||||||
- `IDENTIFIER` is a nonempty string of ASCII letters and underscores.
|
- `IDENTIFIER` is a nonempty string of ASCII letters and underscores.
|
||||||
- The `repeat` forms apply to the adjacent `element`, and are as follows:
|
- The `repeat` forms apply to the adjacent `element`, and are as follows:
|
||||||
- `?` means zero or one repetition
|
- `?` means zero or one repetition
|
||||||
@ -66,9 +66,9 @@ This EBNF dialect should hopefully be familiar to many readers.
|
|||||||
|
|
||||||
## Unicode productions
|
## Unicode productions
|
||||||
|
|
||||||
A few productions in Rust's grammar permit Unicode codepoints outside the ASCII
|
A few productions in Rust's grammar permit Unicode code points outside the ASCII
|
||||||
range. We define these productions in terms of character properties specified
|
range. We define these productions in terms of character properties specified
|
||||||
in the Unicode standard, rather than in terms of ASCII-range codepoints. The
|
in the Unicode standard, rather than in terms of ASCII-range code points. The
|
||||||
section [Special Unicode Productions](#special-unicode-productions) lists these
|
section [Special Unicode Productions](#special-unicode-productions) lists these
|
||||||
productions.
|
productions.
|
||||||
|
|
||||||
@ -91,10 +91,10 @@ production. See [tokens](#tokens) for more information.
|
|||||||
|
|
||||||
## Input format
|
## Input format
|
||||||
|
|
||||||
Rust input is interpreted as a sequence of Unicode codepoints encoded in UTF-8.
|
Rust input is interpreted as a sequence of Unicode code points encoded in UTF-8.
|
||||||
Most Rust grammar rules are defined in terms of printable ASCII-range
|
Most Rust grammar rules are defined in terms of printable ASCII-range
|
||||||
codepoints, but a small number are defined in terms of Unicode properties or
|
code points, but a small number are defined in terms of Unicode properties or
|
||||||
explicit codepoint lists. [^inputformat]
|
explicit code point lists. [^inputformat]
|
||||||
|
|
||||||
[^inputformat]: Substitute definitions for the special Unicode productions are
|
[^inputformat]: Substitute definitions for the special Unicode productions are
|
||||||
provided to the grammar verifier, restricted to ASCII range, when verifying the
|
provided to the grammar verifier, restricted to ASCII range, when verifying the
|
||||||
@ -147,11 +147,13 @@ comments beginning with exactly one repeated asterisk in the block-open
|
|||||||
sequence (`/**`), are interpreted as a special syntax for `doc`
|
sequence (`/**`), are interpreted as a special syntax for `doc`
|
||||||
[attributes](#attributes). That is, they are equivalent to writing
|
[attributes](#attributes). That is, they are equivalent to writing
|
||||||
`#[doc="..."]` around the body of the comment (this includes the comment
|
`#[doc="..."]` around the body of the comment (this includes the comment
|
||||||
characters themselves, ie `/// Foo` turns into `#[doc="/// Foo"]`).
|
characters themselves, i.e. `/// Foo` turns into `#[doc="/// Foo"]`).
|
||||||
|
|
||||||
`//!` comments apply to the parent of the comment, rather than the item that
|
Line comments beginning with `//!` and block comments beginning with `/*!` are
|
||||||
follows. `//!` comments are usually used to display information on the crate
|
doc comments that apply to the parent of the comment, rather than the item
|
||||||
index page.
|
that follows. That is, they are equivalent to writing `#![doc="..."]` around
|
||||||
|
the body of the comment. `//!` comments are usually used to display
|
||||||
|
information on the crate index page.
|
||||||
|
|
||||||
Non-doc comments are interpreted as a form of whitespace.
|
Non-doc comments are interpreted as a form of whitespace.
|
||||||
|
|
||||||
@ -196,10 +198,11 @@ grammar as double-quoted strings. Other tokens have exact rules given.
|
|||||||
| fn | for | if | impl | in |
|
| fn | for | if | impl | in |
|
||||||
| let | loop | macro | match | mod |
|
| let | loop | macro | match | mod |
|
||||||
| move | mut | offsetof | override | priv |
|
| move | mut | offsetof | override | priv |
|
||||||
| pub | pure | ref | return | sizeof |
|
| proc | pub | pure | ref | return |
|
||||||
| static | self | struct | super | true |
|
| Self | self | sizeof | static | struct |
|
||||||
| trait | type | typeof | unsafe | unsized |
|
| super | trait | true | type | typeof |
|
||||||
| use | virtual | where | while | yield |
|
| unsafe | unsized | use | virtual | where |
|
||||||
|
| while | yield | | | |
|
||||||
|
|
||||||
|
|
||||||
Each of these keywords has special meaning in its grammar, and all of them are
|
Each of these keywords has special meaning in its grammar, and all of them are
|
||||||
@ -330,14 +333,14 @@ Some additional _escapes_ are available in either character or non-raw string
|
|||||||
literals. An escape starts with a `U+005C` (`\`) and continues with one of the
|
literals. An escape starts with a `U+005C` (`\`) and continues with one of the
|
||||||
following forms:
|
following forms:
|
||||||
|
|
||||||
* An _8-bit codepoint escape_ escape starts with `U+0078` (`x`) and is
|
* An _8-bit code point escape_ starts with `U+0078` (`x`) and is
|
||||||
followed by exactly two _hex digits_. It denotes the Unicode codepoint
|
followed by exactly two _hex digits_. It denotes the Unicode code point
|
||||||
equal to the provided hex value.
|
equal to the provided hex value.
|
||||||
* A _24-bit codepoint escape_ starts with `U+0075` (`u`) and is followed
|
* A _24-bit code point escape_ starts with `U+0075` (`u`) and is followed
|
||||||
by up to six _hex digits_ surrounded by braces `U+007B` (`{`) and `U+007D`
|
by up to six _hex digits_ surrounded by braces `U+007B` (`{`) and `U+007D`
|
||||||
(`}`). It denotes the Unicode codepoint equal to the provided hex value.
|
(`}`). It denotes the Unicode code point equal to the provided hex value.
|
||||||
* A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072`
|
* A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072`
|
||||||
(`r`), or `U+0074` (`t`), denoting the unicode values `U+000A` (LF),
|
(`r`), or `U+0074` (`t`), denoting the Unicode values `U+000A` (LF),
|
||||||
`U+000D` (CR) or `U+0009` (HT) respectively.
|
`U+000D` (CR) or `U+0009` (HT) respectively.
|
||||||
* The _backslash escape_ is the character `U+005C` (`\`) which must be
|
* The _backslash escape_ is the character `U+005C` (`\`) which must be
|
||||||
escaped in order to denote *itself*.
|
escaped in order to denote *itself*.
|
||||||
@ -407,7 +410,7 @@ Some additional _escapes_ are available in either byte or non-raw byte string
|
|||||||
literals. An escape starts with a `U+005C` (`\`) and continues with one of the
|
literals. An escape starts with a `U+005C` (`\`) and continues with one of the
|
||||||
following forms:
|
following forms:
|
||||||
|
|
||||||
* An _byte escape_ escape starts with `U+0078` (`x`) and is
|
* A _byte escape_ escape starts with `U+0078` (`x`) and is
|
||||||
followed by exactly two _hex digits_. It denotes the byte
|
followed by exactly two _hex digits_. It denotes the byte
|
||||||
equal to the provided hex value.
|
equal to the provided hex value.
|
||||||
* A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072`
|
* A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072`
|
||||||
@ -697,9 +700,9 @@ in macro rules). In the transcriber, the designator is already known, and so
|
|||||||
only the name of a matched nonterminal comes after the dollar sign.
|
only the name of a matched nonterminal comes after the dollar sign.
|
||||||
|
|
||||||
In both the matcher and transcriber, the Kleene star-like operator indicates
|
In both the matcher and transcriber, the Kleene star-like operator indicates
|
||||||
repetition. The Kleene star operator consists of `$` and parens, optionally
|
repetition. The Kleene star operator consists of `$` and parentheses, optionally
|
||||||
followed by a separator token, followed by `*` or `+`. `*` means zero or more
|
followed by a separator token, followed by `*` or `+`. `*` means zero or more
|
||||||
repetitions, `+` means at least one repetition. The parens are not matched or
|
repetitions, `+` means at least one repetition. The parentheses are not matched or
|
||||||
transcribed. On the matcher side, a name is bound to _all_ of the names it
|
transcribed. On the matcher side, a name is bound to _all_ of the names it
|
||||||
matches, in a structure that mimics the structure of the repetition encountered
|
matches, in a structure that mimics the structure of the repetition encountered
|
||||||
on a successful match. The job of the transcriber is to sort that structure
|
on a successful match. The job of the transcriber is to sort that structure
|
||||||
@ -1099,40 +1102,31 @@ signature. Each type parameter must be explicitly declared, in an
|
|||||||
angle-bracket-enclosed, comma-separated list following the function name.
|
angle-bracket-enclosed, comma-separated list following the function name.
|
||||||
|
|
||||||
```{.ignore}
|
```{.ignore}
|
||||||
fn iter<T>(seq: &[T], f: |T|) {
|
fn iter<T, F>(seq: &[T], f: F) where T: Copy, F: Fn(T) {
|
||||||
for elt in seq.iter() { f(elt); }
|
for elt in seq { f(*elt); }
|
||||||
}
|
}
|
||||||
fn map<T, U>(seq: &[T], f: |T| -> U) -> Vec<U> {
|
fn map<T, U, F>(seq: &[T], f: F) -> Vec<U> where T: Copy, U: Copy, F: Fn(T) -> U {
|
||||||
let mut acc = vec![];
|
let mut acc = vec![];
|
||||||
for elt in seq.iter() { acc.push(f(elt)); }
|
for elt in seq { acc.push(f(*elt)); }
|
||||||
acc
|
acc
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Inside the function signature and body, the name of the type parameter can be
|
Inside the function signature and body, the name of the type parameter can be
|
||||||
used as a type name.
|
used as a type name. [Trait](#traits) bounds can be specified for type parameters
|
||||||
|
to allow methods with that trait to be called on values of that type. This is
|
||||||
|
specified using the `where` syntax, as in the above example.
|
||||||
|
|
||||||
When a generic function is referenced, its type is instantiated based on the
|
When a generic function is referenced, its type is instantiated based on the
|
||||||
context of the reference. For example, calling the `iter` function defined
|
context of the reference. For example, calling the `iter` function defined
|
||||||
above on `[1, 2]` will instantiate type parameter `T` with `i32`, and require
|
above on `[1, 2]` will instantiate type parameter `T` with `i32`, and require
|
||||||
the closure parameter to have type `fn(i32)`.
|
the closure parameter to have type `Fn(i32)`.
|
||||||
|
|
||||||
The type parameters can also be explicitly supplied in a trailing
|
The type parameters can also be explicitly supplied in a trailing
|
||||||
[path](#paths) component after the function name. This might be necessary if
|
[path](#paths) component after the function name. This might be necessary if
|
||||||
there is not sufficient context to determine the type parameters. For example,
|
there is not sufficient context to determine the type parameters. For example,
|
||||||
`mem::size_of::<u32>() == 4`.
|
`mem::size_of::<u32>() == 4`.
|
||||||
|
|
||||||
Since a parameter type is opaque to the generic function, the set of operations
|
|
||||||
that can be performed on it is limited. Values of parameter type can only be
|
|
||||||
moved, not copied.
|
|
||||||
|
|
||||||
```
|
|
||||||
fn id<T>(x: T) -> T { x }
|
|
||||||
```
|
|
||||||
|
|
||||||
Similarly, [trait](#traits) bounds can be specified for type parameters to
|
|
||||||
allow methods with that trait to be called on values of that type.
|
|
||||||
|
|
||||||
#### Unsafety
|
#### Unsafety
|
||||||
|
|
||||||
Unsafe operations are those that potentially violate the memory-safety
|
Unsafe operations are those that potentially violate the memory-safety
|
||||||
@ -1209,9 +1203,9 @@ the guarantee that these issues are never caused by safe code.
|
|||||||
|
|
||||||
[noalias]: http://llvm.org/docs/LangRef.html#noalias
|
[noalias]: http://llvm.org/docs/LangRef.html#noalias
|
||||||
|
|
||||||
##### Behaviour not considered unsafe
|
##### Behavior not considered unsafe
|
||||||
|
|
||||||
This is a list of behaviour not considered *unsafe* in Rust terms, but that may
|
This is a list of behavior not considered *unsafe* in Rust terms, but that may
|
||||||
be undesired.
|
be undesired.
|
||||||
|
|
||||||
* Deadlocks
|
* Deadlocks
|
||||||
@ -1304,7 +1298,7 @@ specific type, but may implement several different traits, or be compatible with
|
|||||||
several different type constraints.
|
several different type constraints.
|
||||||
|
|
||||||
For example, the following defines the type `Point` as a synonym for the type
|
For example, the following defines the type `Point` as a synonym for the type
|
||||||
`(u8, u8)`, the type of pairs of unsigned 8 bit integers.:
|
`(u8, u8)`, the type of pairs of unsigned 8 bit integers:
|
||||||
|
|
||||||
```
|
```
|
||||||
type Point = (u8, u8);
|
type Point = (u8, u8);
|
||||||
@ -1555,7 +1549,7 @@ fn draw_twice<T: Shape>(surface: Surface, sh: T) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Traits also define an [object type](#object-types) with the same name as the
|
Traits also define an [trait object](#trait-objects) with the same name as the
|
||||||
trait. Values of this type are created by [casting](#type-cast-expressions)
|
trait. Values of this type are created by [casting](#type-cast-expressions)
|
||||||
pointer values (pointing to a type for which an implementation of the given
|
pointer values (pointing to a type for which an implementation of the given
|
||||||
trait is in scope) to pointers to the trait name, used as a type.
|
trait is in scope) to pointers to the trait name, used as a type.
|
||||||
@ -1958,7 +1952,7 @@ type int8_t = i8;
|
|||||||
|
|
||||||
### Crate-only attributes
|
### Crate-only attributes
|
||||||
|
|
||||||
- `crate_name` - specify the this crate's crate name.
|
- `crate_name` - specify the crate's crate name.
|
||||||
- `crate_type` - see [linkage](#linkage).
|
- `crate_type` - see [linkage](#linkage).
|
||||||
- `feature` - see [compiler features](#compiler-features).
|
- `feature` - see [compiler features](#compiler-features).
|
||||||
- `no_builtins` - disable optimizing certain code patterns to invocations of
|
- `no_builtins` - disable optimizing certain code patterns to invocations of
|
||||||
@ -2146,7 +2140,7 @@ The following configurations must be defined by the implementation:
|
|||||||
`"unix"` or `"windows"`. The value of this configuration option is defined
|
`"unix"` or `"windows"`. The value of this configuration option is defined
|
||||||
as a configuration itself, like `unix` or `windows`.
|
as a configuration itself, like `unix` or `windows`.
|
||||||
* `target_os = "..."`. Operating system of the target, examples include
|
* `target_os = "..."`. Operating system of the target, examples include
|
||||||
`"win32"`, `"macos"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"`,
|
`"windows"`, `"macos"`, `"ios"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"`,
|
||||||
`"bitrig"` or `"openbsd"`.
|
`"bitrig"` or `"openbsd"`.
|
||||||
* `target_pointer_width = "..."`. Target pointer width in bits. This is set
|
* `target_pointer_width = "..."`. Target pointer width in bits. This is set
|
||||||
to `"32"` for targets with 32-bit pointers, and likewise set to `"64"` for
|
to `"32"` for targets with 32-bit pointers, and likewise set to `"64"` for
|
||||||
@ -2744,7 +2738,7 @@ A _method call_ consists of an expression followed by a single dot, an
|
|||||||
identifier, and a parenthesized expression-list. Method calls are resolved to
|
identifier, and a parenthesized expression-list. Method calls are resolved to
|
||||||
methods on specific traits, either statically dispatching to a method if the
|
methods on specific traits, either statically dispatching to a method if the
|
||||||
exact `self`-type of the left-hand-side is known, or dynamically dispatching if
|
exact `self`-type of the left-hand-side is known, or dynamically dispatching if
|
||||||
the left-hand-side expression is an indirect [object type](#object-types).
|
the left-hand-side expression is an indirect [trait object](#trait-objects).
|
||||||
|
|
||||||
### Field expressions
|
### Field expressions
|
||||||
|
|
||||||
@ -2812,6 +2806,33 @@ _panicked state_.
|
|||||||
(["a", "b"])[10]; // panics
|
(["a", "b"])[10]; // panics
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Range expressions
|
||||||
|
|
||||||
|
```{.ebnf .gram}
|
||||||
|
range_expr : expr ".." expr |
|
||||||
|
expr ".." |
|
||||||
|
".." expr |
|
||||||
|
".." ;
|
||||||
|
```
|
||||||
|
|
||||||
|
The `..` operator will construct an object of one of the `std::ops::Range` variants.
|
||||||
|
|
||||||
|
```
|
||||||
|
1..2; // std::ops::Range
|
||||||
|
3..; // std::ops::RangeFrom
|
||||||
|
..4; // std::ops::RangeTo
|
||||||
|
..; // std::ops::RangeFull
|
||||||
|
```
|
||||||
|
|
||||||
|
The following expressions are equivalent.
|
||||||
|
|
||||||
|
```
|
||||||
|
let x = std::ops::Range {start: 0, end: 10};
|
||||||
|
let y = 0..10;
|
||||||
|
|
||||||
|
assert_eq!(x,y);
|
||||||
|
```
|
||||||
|
|
||||||
### Unary operator expressions
|
### Unary operator expressions
|
||||||
|
|
||||||
Rust defines three unary operators. They are all written as prefix operators,
|
Rust defines three unary operators. They are all written as prefix operators,
|
||||||
@ -3078,6 +3099,50 @@ fn ten_times<F>(f: F) where F: Fn(i32) {
|
|||||||
ten_times(|j| println!("hello, {}", j));
|
ten_times(|j| println!("hello, {}", j));
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Infinite loops
|
||||||
|
|
||||||
|
A `loop` expression denotes an infinite loop.
|
||||||
|
|
||||||
|
```{.ebnf .gram}
|
||||||
|
loop_expr : [ lifetime ':' ] "loop" '{' block '}';
|
||||||
|
```
|
||||||
|
|
||||||
|
A `loop` expression may optionally have a _label_. The label is written as
|
||||||
|
a lifetime preceding the loop expression, as in `'foo: loop{ }`. If a
|
||||||
|
label is present, then labeled `break` and `continue` expressions nested
|
||||||
|
within this loop may exit out of this loop or return control to its head.
|
||||||
|
See [Break expressions](#break-expressions) and [Continue
|
||||||
|
expressions](#continue-expressions).
|
||||||
|
|
||||||
|
### Break expressions
|
||||||
|
|
||||||
|
```{.ebnf .gram}
|
||||||
|
break_expr : "break" [ lifetime ];
|
||||||
|
```
|
||||||
|
|
||||||
|
A `break` expression has an optional _label_. If the label is absent, then
|
||||||
|
executing a `break` expression immediately terminates the innermost loop
|
||||||
|
enclosing it. It is only permitted in the body of a loop. If the label is
|
||||||
|
present, then `break 'foo` terminates the loop with label `'foo`, which need not
|
||||||
|
be the innermost label enclosing the `break` expression, but must enclose it.
|
||||||
|
|
||||||
|
### Continue expressions
|
||||||
|
|
||||||
|
```{.ebnf .gram}
|
||||||
|
continue_expr : "continue" [ lifetime ];
|
||||||
|
```
|
||||||
|
|
||||||
|
A `continue` expression has an optional _label_. If the label is absent, then
|
||||||
|
executing a `continue` expression immediately terminates the current iteration
|
||||||
|
of the innermost loop enclosing it, returning control to the loop *head*. In
|
||||||
|
the case of a `while` loop, the head is the conditional expression controlling
|
||||||
|
the loop. In the case of a `for` loop, the head is the call-expression
|
||||||
|
controlling the loop. If the label is present, then `continue 'foo` returns
|
||||||
|
control to the head of the loop with label `'foo`, which need not be the
|
||||||
|
innermost label enclosing the `break` expression, but must enclose it.
|
||||||
|
|
||||||
|
A `continue` expression is only permitted in the body of a loop.
|
||||||
|
|
||||||
### While loops
|
### While loops
|
||||||
|
|
||||||
```{.ebnf .gram}
|
```{.ebnf .gram}
|
||||||
@ -3100,48 +3165,10 @@ while i < 10 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Infinite loops
|
Like `loop` expressions, `while` loops can be controlled with `break` or
|
||||||
|
`continue`, and may optionally have a _label_. See [infinite
|
||||||
A `loop` expression denotes an infinite loop.
|
loops](#infinite-loops), [break expressions](#break-expressions), and
|
||||||
|
[continue expressions](#continue-expressions) for more information.
|
||||||
```{.ebnf .gram}
|
|
||||||
loop_expr : [ lifetime ':' ] "loop" '{' block '}';
|
|
||||||
```
|
|
||||||
|
|
||||||
A `loop` expression may optionally have a _label_. If a label is present, then
|
|
||||||
labeled `break` and `continue` expressions nested within this loop may exit out
|
|
||||||
of this loop or return control to its head. See [Break
|
|
||||||
expressions](#break-expressions) and [Continue
|
|
||||||
expressions](#continue-expressions).
|
|
||||||
|
|
||||||
### Break expressions
|
|
||||||
|
|
||||||
```{.ebnf .gram}
|
|
||||||
break_expr : "break" [ lifetime ];
|
|
||||||
```
|
|
||||||
|
|
||||||
A `break` expression has an optional _label_. If the label is absent, then
|
|
||||||
executing a `break` expression immediately terminates the innermost loop
|
|
||||||
enclosing it. It is only permitted in the body of a loop. If the label is
|
|
||||||
present, then `break foo` terminates the loop with label `foo`, which need not
|
|
||||||
be the innermost label enclosing the `break` expression, but must enclose it.
|
|
||||||
|
|
||||||
### Continue expressions
|
|
||||||
|
|
||||||
```{.ebnf .gram}
|
|
||||||
continue_expr : "continue" [ lifetime ];
|
|
||||||
```
|
|
||||||
|
|
||||||
A `continue` expression has an optional _label_. If the label is absent, then
|
|
||||||
executing a `continue` expression immediately terminates the current iteration
|
|
||||||
of the innermost loop enclosing it, returning control to the loop *head*. In
|
|
||||||
the case of a `while` loop, the head is the conditional expression controlling
|
|
||||||
the loop. In the case of a `for` loop, the head is the call-expression
|
|
||||||
controlling the loop. If the label is present, then `continue foo` returns
|
|
||||||
control to the head of the loop with label `foo`, which need not be the
|
|
||||||
innermost label enclosing the `break` expression, but must enclose it.
|
|
||||||
|
|
||||||
A `continue` expression is only permitted in the body of a loop.
|
|
||||||
|
|
||||||
### For expressions
|
### For expressions
|
||||||
|
|
||||||
@ -3177,6 +3204,11 @@ for i in 0..256 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Like `loop` expressions, `for` loops can be controlled with `break` or
|
||||||
|
`continue`, and may optionally have a _label_. See [infinite
|
||||||
|
loops](#infinite-loops), [break expressions](#break-expressions), and
|
||||||
|
[continue expressions](#continue-expressions) for more information.
|
||||||
|
|
||||||
### If expressions
|
### If expressions
|
||||||
|
|
||||||
```{.ebnf .gram}
|
```{.ebnf .gram}
|
||||||
@ -3432,7 +3464,7 @@ is not a surrogate), represented as a 32-bit unsigned word in the 0x0000 to
|
|||||||
UTF-32 string.
|
UTF-32 string.
|
||||||
|
|
||||||
A value of type `str` is a Unicode string, represented as an array of 8-bit
|
A value of type `str` is a Unicode string, represented as an array of 8-bit
|
||||||
unsigned bytes holding a sequence of UTF-8 codepoints. Since `str` is of
|
unsigned bytes holding a sequence of UTF-8 code points. Since `str` is of
|
||||||
unknown size, it is not a _first-class_ type, but can only be instantiated
|
unknown size, it is not a _first-class_ type, but can only be instantiated
|
||||||
through a pointer type, such as `&str` or `String`.
|
through a pointer type, such as `&str` or `String`.
|
||||||
|
|
||||||
@ -3649,23 +3681,23 @@ call_closure(closure_no_args, closure_args);
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Object types
|
### Trait objects
|
||||||
|
|
||||||
Every trait item (see [traits](#traits)) defines a type with the same name as
|
Every trait item (see [traits](#traits)) defines a type with the same name as
|
||||||
the trait. This type is called the _object type_ of the trait. Object types
|
the trait. This type is called the _trait object_ of the trait. Trait objects
|
||||||
permit "late binding" of methods, dispatched using _virtual method tables_
|
permit "late binding" of methods, dispatched using _virtual method tables_
|
||||||
("vtables"). Whereas most calls to trait methods are "early bound" (statically
|
("vtables"). Whereas most calls to trait methods are "early bound" (statically
|
||||||
resolved) to specific implementations at compile time, a call to a method on an
|
resolved) to specific implementations at compile time, a call to a method on an
|
||||||
object type is only resolved to a vtable entry at compile time. The actual
|
trait objects is only resolved to a vtable entry at compile time. The actual
|
||||||
implementation for each vtable entry can vary on an object-by-object basis.
|
implementation for each vtable entry can vary on an object-by-object basis.
|
||||||
|
|
||||||
Given a pointer-typed expression `E` of type `&T` or `Box<T>`, where `T`
|
Given a pointer-typed expression `E` of type `&T` or `Box<T>`, where `T`
|
||||||
implements trait `R`, casting `E` to the corresponding pointer type `&R` or
|
implements trait `R`, casting `E` to the corresponding pointer type `&R` or
|
||||||
`Box<R>` results in a value of the _object type_ `R`. This result is
|
`Box<R>` results in a value of the _trait object_ `R`. This result is
|
||||||
represented as a pair of pointers: the vtable pointer for the `T`
|
represented as a pair of pointers: the vtable pointer for the `T`
|
||||||
implementation of `R`, and the pointer value of `E`.
|
implementation of `R`, and the pointer value of `E`.
|
||||||
|
|
||||||
An example of an object type:
|
An example of a trait object:
|
||||||
|
|
||||||
```
|
```
|
||||||
trait Printable {
|
trait Printable {
|
||||||
@ -3685,7 +3717,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
In this example, the trait `Printable` occurs as an object type in both the
|
In this example, the trait `Printable` occurs as a trait object in both the
|
||||||
type signature of `print`, and the cast expression in `main`.
|
type signature of `print`, and the cast expression in `main`.
|
||||||
|
|
||||||
### Type parameters
|
### Type parameters
|
||||||
|
@ -57,8 +57,7 @@ let x: Vec<u32> = {
|
|||||||
We can implement this shorthand, using a macro: [^actual]
|
We can implement this shorthand, using a macro: [^actual]
|
||||||
|
|
||||||
[^actual]: The actual definition of `vec!` in libcollections differs from the
|
[^actual]: The actual definition of `vec!` in libcollections differs from the
|
||||||
one presented here, for reasons of efficiency and reusability. Some
|
one presented here, for reasons of efficiency and reusability.
|
||||||
of these are mentioned in the [advanced macros chapter][].
|
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
macro_rules! vec {
|
macro_rules! vec {
|
||||||
@ -106,7 +105,7 @@ These have [their own little grammar] within the language.
|
|||||||
|
|
||||||
The matcher `$x:expr` will match any Rust expression, binding that syntax tree
|
The matcher `$x:expr` will match any Rust expression, binding that syntax tree
|
||||||
to the ‘metavariable’ `$x`. The identifier `expr` is a ‘fragment specifier’;
|
to the ‘metavariable’ `$x`. The identifier `expr` is a ‘fragment specifier’;
|
||||||
the full possibilities are enumerated in the [advanced macros chapter][].
|
the full possibilities are enumerated later in this chapter.
|
||||||
Surrounding the matcher with `$(...),*` will match zero or more expressions,
|
Surrounding the matcher with `$(...),*` will match zero or more expressions,
|
||||||
separated by commas.
|
separated by commas.
|
||||||
|
|
||||||
@ -566,7 +565,7 @@ When this library is loaded with `#[macro_use] extern crate`, only `m2` will
|
|||||||
be imported.
|
be imported.
|
||||||
|
|
||||||
The Rust Reference has a [listing of macro-related
|
The Rust Reference has a [listing of macro-related
|
||||||
attributes](../reference.html#macro--and-plugin-related-attributes).
|
attributes](../reference.html#macro-related-attributes).
|
||||||
|
|
||||||
# The variable `$crate`
|
# The variable `$crate`
|
||||||
|
|
||||||
|
@ -1151,8 +1151,8 @@ impl<'a> Parser<'a> {
|
|||||||
&token::CloseDelim(token::Brace),
|
&token::CloseDelim(token::Brace),
|
||||||
seq_sep_none(),
|
seq_sep_none(),
|
||||||
|p| {
|
|p| {
|
||||||
let lo = p.span.lo;
|
|
||||||
let mut attrs = p.parse_outer_attributes();
|
let mut attrs = p.parse_outer_attributes();
|
||||||
|
let lo = p.span.lo;
|
||||||
|
|
||||||
let (name, node) = if try!(p.eat_keyword(keywords::Type)) {
|
let (name, node) = if try!(p.eat_keyword(keywords::Type)) {
|
||||||
let TyParam {ident, bounds, default, ..} = try!(p.parse_ty_param());
|
let TyParam {ident, bounds, default, ..} = try!(p.parse_ty_param());
|
||||||
@ -3409,8 +3409,8 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lo = self.span.lo;
|
|
||||||
let attrs = self.parse_outer_attributes();
|
let attrs = self.parse_outer_attributes();
|
||||||
|
let lo = self.span.lo;
|
||||||
|
|
||||||
Ok(Some(if self.check_keyword(keywords::Let) {
|
Ok(Some(if self.check_keyword(keywords::Let) {
|
||||||
check_expected_item(self, &attrs);
|
check_expected_item(self, &attrs);
|
||||||
@ -4304,8 +4304,8 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
/// Parse an impl item.
|
/// Parse an impl item.
|
||||||
pub fn parse_impl_item(&mut self) -> PResult<P<ImplItem>> {
|
pub fn parse_impl_item(&mut self) -> PResult<P<ImplItem>> {
|
||||||
let lo = self.span.lo;
|
|
||||||
let mut attrs = self.parse_outer_attributes();
|
let mut attrs = self.parse_outer_attributes();
|
||||||
|
let lo = self.span.lo;
|
||||||
let vis = try!(self.parse_visibility());
|
let vis = try!(self.parse_visibility());
|
||||||
let (name, node) = if try!(self.eat_keyword(keywords::Type)) {
|
let (name, node) = if try!(self.eat_keyword(keywords::Type)) {
|
||||||
let name = try!(self.parse_ident());
|
let name = try!(self.parse_ident());
|
||||||
@ -5380,9 +5380,8 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
/// Parse a foreign item.
|
/// Parse a foreign item.
|
||||||
fn parse_foreign_item(&mut self) -> PResult<Option<P<ForeignItem>>> {
|
fn parse_foreign_item(&mut self) -> PResult<Option<P<ForeignItem>>> {
|
||||||
let lo = self.span.lo;
|
|
||||||
|
|
||||||
let attrs = self.parse_outer_attributes();
|
let attrs = self.parse_outer_attributes();
|
||||||
|
let lo = self.span.lo;
|
||||||
let visibility = try!(self.parse_visibility());
|
let visibility = try!(self.parse_visibility());
|
||||||
|
|
||||||
if self.check_keyword(keywords::Static) {
|
if self.check_keyword(keywords::Static) {
|
||||||
|
Loading…
Reference in New Issue
Block a user