Skip to content

Commit 4f39ffb

Browse files
committed
Make some small improvements to phrasing and examples
1 parent b75f52a commit 4f39ffb

File tree

1 file changed

+90
-74
lines changed

1 file changed

+90
-74
lines changed

src/expressions.md

+90-74
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ rvalue context. All other expression contexts are rvalue contexts.
4242

4343
When an lvalue is evaluated in an _rvalue context_, it denotes the value held
4444
_in_ that memory location. If value is of a type that implements `Copy`, then
45-
the value will be copied. In other situations if the type of the value is
46-
[`Sized`](the-sized-trait.html) it may be possible to move the value. Only the
47-
following lvalues may be moved out of:
45+
the value will be copied. In the remaining situations if the type of the value
46+
is [`Sized`](the-sized-trait.html) it may be possible to move the value. Only
47+
the following lvalues may be moved out of:
4848

49-
* [Variables](#variables.html) which are not currently borrowed.
49+
* [Variables](variables.html) which are not currently borrowed.
5050
* [Temporary values](#temporary-lifetimes).
5151
* [Fields](#field-expressions) of an lvalue which can be moved out of and
5252
doesn't implement [`Drop`](#the-drop-trait).
@@ -67,14 +67,14 @@ _immutable_.
6767

6868
The following expressions can create mutable lvalues:
6969

70-
* Mutable [variables](#variables.html), which are not currently borrowed.
70+
* Mutable [variables](variables.html), which are not currently borrowed.
7171
* [Mutable `static` items](items.html#mutable-statics).
7272
* [Temporary values](#temporary-lifetimes).
73-
* [Fields](#field-expressions), this evaluates the expression in a mutable
73+
* [Fields](#field-expressions), this evaluates the subexpression in a mutable
7474
lvalue context.
7575
* [Dereferenes](#the-dereference-operator) of a `*mut T` pointer.
7676
* Dereference of a variable, or field of a variable, with type `&mut T`. Note:
77-
this is an exception to the next rule.
77+
this is an exception to the requirement for the next rule.
7878
* Dereferences of a type that implements `DerefMut`, this then requires that
7979
the value being dereferenced is evaluated is a mutable lvalue context.
8080
* [Indexing](#index-expressions) of a type that implements `DerefMut`, this
@@ -127,8 +127,13 @@ borrowing it. For example, it is possible to compare two unsized
127127
operator implicitly borrows it's operands:
128128

129129
```rust
130-
let a: &[i32] = &[1, 2, 3];
131-
let b: &[i32] = &vec![1, 2, 3];
130+
# let c = [1, 2, 3];
131+
# let d = vec![1, 2, 3];
132+
let a: &[i32];
133+
let b: &[i32];
134+
# a = &c;
135+
# b = &d;
136+
// ...
132137
*a == *b;
133138
// Equivalent form:
134139
::std::cmp::PartialEq::eq(&*a, &*b);
@@ -144,12 +149,6 @@ Implicit borrows may be taken in the following expressions:
144149
* Operands of [comparison operators](#comparison-operators).
145150
* Left operands of the [compound assignment](#compound-assignment-expressions).
146151

147-
## Traits
148-
149-
Many of the following operators and expressions can also be overloaded for
150-
other types using traits in `std::ops` or `std::cmp`, these traits here also
151-
exist in `core::ops` and `core::cmp` with the same names.
152-
153152
## Constant expressions
154153

155154
Certain types of expressions can be evaluated at compile time. These are called
@@ -166,10 +165,11 @@ The following expressions are constant expressions, so long as any operands are
166165
also constant expressions:
167166

168167
* [Literals](#literal-expressions).
169-
* [Paths](#paths) to [functions](items.html#functions) and constants. Recursively
170-
defining constants is not allowed.
171-
* Statics, so long as only their address, not their value, is used: even
172-
indirectly through a compilicated constant expression. \*
168+
* [Paths](#paths) to [functions](items.html#functions) and constants.
169+
Recursively defining constants is not allowed.
170+
* Paths to statics, so long as only their address, not their value, is used.
171+
This includes using their value indirectly through a compilicated expression.
172+
\*
173173
* [Tuple expressions](#tuple-expressions).
174174
* [Array expressions](#array-expressions).
175175
* [Struct expressions](#struct-expressions), where the type does not implement
@@ -182,8 +182,8 @@ also constant expressions:
182182
* [Index expressions](#index-expressions), indexing a [array or
183183
slice](types.html#array-and-slice-types) with a `usize`.
184184
* [Range expressions](#range-expressions).
185-
* [Closure expressions](#closure-expressions) which don't capture variables from
186-
the environment.
185+
* [Closure expressions](#closure-expressions) which don't capture variables
186+
from the environment.
187187
* Built in [negation](#negation-operators), [arithmetic,
188188
logical](#arithmetic-and-logical-binary-operators),
189189
[comparison](#comparison-operators) or [lazy
@@ -198,6 +198,12 @@ also constant expressions:
198198

199199
\* Only in static items.
200200

201+
## Overloading Traits
202+
203+
Many of the following operators and expressions can also be overloaded for
204+
other types using traits in `std::ops` or `std::cmp`, these traits here also
205+
exist in `core::ops` and `core::cmp` with the same names.
206+
201207
## Literal expressions
202208

203209
A _literal expression_ consists of one of the [literal](tokens.html#literals)
@@ -215,20 +221,20 @@ boolean value, or the unit value.
215221

216222
A [path](paths.html) used as an expression context denotes either a local
217223
variable or an item. Path expressions that resolve to local or static variables
218-
are [lvalues](expressions.html#lvalues-rvalues-and-temporaries). Using a
219-
`static mut` variable requires an [`unsafe` block](#unsafe-block) Other
220-
paths are rvalues.
224+
are [lvalues](expressions.html#lvalues-rvalues-and-temporaries), other paths
225+
are rvalues. Using a `static mut` variable requires an [`unsafe`
226+
block](#unsafe-block).
221227

222228
```rust
223-
mod globals {
224-
pub static STATIC_VAR: i32 = 5;
225-
pub static mut STATIC_MUT_VAR: i32 = 7;
226-
}
227-
let local_var = 3;
229+
# mod globals {
230+
# pub static STATIC_VAR: i32 = 5;
231+
# pub static mut STATIC_MUT_VAR: i32 = 7;
232+
# }
233+
# let local_var = 3;
228234
local_var;
229235
globals::STATIC_VAR;
230236
unsafe { globals::STATIC_MUT_VAR };
231-
let some_constructor = Option::Some::<i32>;
237+
let some_constructor = Some::<i32>;
232238
let push_integer = Vec::<i32>::push;
233239
let slice_reverse = <[i32]>::reverse;
234240
```
@@ -301,7 +307,8 @@ entire expression denotes the result of constructing a new struct (with the
301307
same type as the base expression) with the given values for the fields that
302308
were explicitly specified and the values in the base expression for all other
303309
fields. Just as with all struct expressions, all of the fields of the struct
304-
must be [visible](visibility-and-privacy.html).
310+
must be [visible](visibility-and-privacy.html), even those not explicitly
311+
named.
305312

306313
```rust
307314
# struct Point3d { x: i32, y: i32, z: i32 }
@@ -329,7 +336,7 @@ Point3d { x, y: y_value, z };
329336
### Enumeration Variant expressions
330337

331338
Enumeration variants can be constructed similarly to structs, using a path to
332-
an enum variant instead of a struct:
339+
an enum variant instead of to a struct:
333340

334341
```rust
335342
# enum Message {
@@ -345,12 +352,14 @@ let m = Message::Move { x: 50, y: 200 };
345352
## Block expressions
346353

347354
A _block expression_ is similar to a module in terms of the declarations that
348-
are possible. Each block conceptually introduces a new namespace scope. Use
355+
are possible, but can also contain [statements](statements.html) and end with
356+
an expression. Each block conceptually introduces a new namespace scope. Use
349357
items can bring new names into scopes and declared items are in scope for only
350358
the block itself.
351359

352360
A block will execute each statement sequentially, and then execute the
353-
expression (if given). If the block ends in a statement, its value is `()`:
361+
expression (if given). If the block doesn't end in an expression, its value is
362+
`()`:
354363

355364
```rust
356365
let x: () = { println!("Hello."); };
@@ -365,7 +374,8 @@ assert_eq!(5, x);
365374
```
366375

367376
Blocks are always [rvalues](#lvalues-and-rvalues) and evaluate the last
368-
expression in rvalue context.
377+
expression in rvalue context. This can be used to force moving a value
378+
if really needed.
369379

370380
### `unsafe` blocks
371381

@@ -392,6 +402,7 @@ let log_pi = pi.unwrap_or(1.0).log(2.72);
392402

393403
When resolving method calls on an expression of type `A`, Rust will use the
394404
following order:
405+
395406
1. Inherent methods, with receiver of type `A`, `&A`, `&mut A`.
396407
1. Trait methods with receiver of type `A`.
397408
1. Trait methods with receiver of type `&A`.
@@ -401,8 +412,8 @@ following order:
401412
1. If `A` is now an [array](types.html#array-and-slice-types) type, then
402413
repeat steps 1-4 with the corresponding slice type.
403414

404-
Note: that in steps 1-4 the receiver is used, not the type of `Self`, which may
405-
not be the same as `A`. For example
415+
Note: that in steps 1-4 the receiver is used, not the type of `Self` nor the
416+
type of `A`. For example
406417

407418
```rust,ignore
408419
// `Self` is `&A`, receiver is `&A`.
@@ -442,8 +453,8 @@ mystruct.method(); // Method expression
442453
```
443454

444455
A field access is an [lvalue](expressions.html#lvalues-rvalues-and-temporaries)
445-
referring to the value of that field. When the type providing the field
446-
inherits mutability, it can be [assigned](#assignment-expressions) to.
456+
referring to the value of that field. When the subexpression is
457+
[mutable](#mutability), the field expression is also mutable.
447458

448459
Also, if the type of the expression to the left of the dot is a pointer, it is
449460
automatically dereferenced as many times as necessary to make the field access
@@ -453,7 +464,7 @@ Finally the fields of a struct, a reference to a struct are treated as separate
453464
entities when borrowing. If the struct does not implement
454465
[`Drop`](#the-drop-trait) this also applies to moving out of each of its fields
455466
where possible. This also does not apply if automatic dereferencing is done
456-
though other types.
467+
though user defined types.
457468

458469
```rust
459470
# struct A { f1: String, f2: String, f3: String }
@@ -464,18 +475,18 @@ though other types.
464475
# };
465476
let a: &mut String = &mut x.f1; // x.f1 borrowed mutably
466477
let b: &String = &x.f2; // x.f2 borrowed immutably
467-
let c: &String = &x.f2;
478+
let c: &String = &x.f2; // Can borrow again
468479
let d: String = x.f3; // Move out of x.f3
469480
```
470481

471482
### Tuple indexing expressions
472483

473484
[Tuples](types.html#tuple-types) and [struct tuples](items.html#structs) can be
474485
indexed using the number corresponding to the possition of the field. The index
475-
must be a [decimal literal](tokens.html#integer-literals) with no underscores
476-
or suffix. Tuple indexing expressions also differ from field expressions in
477-
that they can unambiguously be called as a function. In all other aspects they
478-
have the same behavior.
486+
must be written as a [decimal literal](tokens.html#integer-literals) with no
487+
underscores or suffix. Tuple indexing expressions also differ from field
488+
expressions in that they can unambiguously be called as a function. In all
489+
other aspects they have the same behavior.
479490

480491
```rust
481492
# struct Point(f32, f32);
@@ -577,14 +588,13 @@ Refer to [RFC 132] for further details and motivations.
577588

578589
## Closure expressions
579590

580-
A _closure expression_ (sometimes called an "anonymous function expression")
581-
defines a closure and denotes it as a value, in a single expression. A closure
582-
expression is a pipe-symbol-delimited (`|`) list of patterns followed by an
583-
expression. Type annotations may optionally be added for the type of the
584-
parameters or for the return type. If there is a return type, the expression
585-
used for the body of the closure must be a normal [block](#block-expressions).
586-
A closure expression also may begin with the `move` keyword before the initial
587-
`|`.
591+
A _closure expression_ defines a closure and denotes it as a value, in a single
592+
expression. A closure expression is a pipe-symbol-delimited (`|`) list of
593+
patterns followed by an expression. Type annotations may optionally be added
594+
for the type of the parameters or for the return type. If there is a return
595+
type, the expression used for the body of the closure must be a normal
596+
[block](#block-expressions). A closure expression also may begin with the
597+
`move` keyword before the initial `|`.
588598

589599
A closure expression denotes a function that maps a list of parameters
590600
(`ident_list`) onto the expression that follows the `ident_list`. The patterns
@@ -608,10 +618,10 @@ closure's type is `'static`.
608618

609619
The compiler will determine which of the [closure
610620
traits](types.html#closure-types) the closure's type will implement by how it
611-
acts on them. The closure will also implement [`Send`](the-send-trait.html)
612-
and/or [`Sync`](the-sync-trait.html) if all of its captured types do. These
613-
traits allow functions to accept closures using generics, even though the exact
614-
types can't be named.
621+
acts on its captured variables. The closure will also implement
622+
[`Send`](the-send-trait.html) and/or [`Sync`](the-sync-trait.html) if all of
623+
its captured types do. These traits allow functions to accept closures using
624+
generics, even though the exact types can't be named.
615625

616626
In this example, we define a function `ten_times` that takes a higher-order
617627
function argument, and we then call it with a closure expression as an argument,
@@ -625,24 +635,26 @@ fn ten_times<F>(f: F) where F: Fn(i32) {
625635
}
626636

627637
ten_times(|j| println!("hello, {}", j));
638+
// With type annotations
639+
ten_times(|j: i32| -> () { println!("hello, {}", j) });
628640

629641
let word = "konnichiwa".to_owned();
630642
ten_times(move |j| println!("{}, {}", word, j));
631643
```
632644

633645
## Array expressions
634646

635-
An [array](types.html#array-and-slice-types) _expression_ can be written by
647+
An _[array](types.html#array-and-slice-types) expression_ can be written by
636648
enclosing zero or more comma-separated expressions of uniform type in square
637649
brackets. This produces and array containing each of these values in the
638650
order they are written.
639651

640652
Alternatively there can be exactly two expressions inside the brackets,
641653
separated by a semi-colon. The expression after the `;` must be a have type
642-
`usize` and be a constant expression that can be evaluated at compile time,
643-
such as a [literal](tokens.html#literals) or a [constant item
644-
item](items.html#constant-items). `[a; b]` creates an array containing `b` copies
645-
of the value of `a`. If the expression after the semi-colon has a value
654+
`usize` and be a [constant expression](#constant-expressions), such as a
655+
[literal](tokens.html#literals) or a [constant
656+
item](items.html#constant-items). `[a; b]` creates an array containing `b`
657+
copies of the value of `a`. If the expression after the semi-colon has a value
646658
greater than 1 then this requires that the type of `a` is
647659
[`Copy`](the-copy-trait.html).
648660

@@ -715,6 +727,7 @@ Integer operators will panic when they overflow when compiled in debug mode.
715727
The `-C debug-assertions` and `-C overflow-checks` compiler flags can be used
716728
to control this more directly. The following things are considered to be
717729
overflow:
730+
718731
* When `+`, `*` or `-` create a value greater than the maximum value, or less
719732
than the minimum value that can be stored. This includes unary `-` on the
720733
smallest value of any signed integer type.
@@ -759,7 +772,7 @@ resulting [lvalue](expressions.html#lvalues-rvalues-and-temporaries) can be
759772
assigned to. Dereferencing a raw pointer requires `unsafe`.
760773

761774
On non-pointer types `*x` is equivalent to `*std::ops::Deref::deref(&x)` in an
762-
[immutable lvalue context](#mutability) and`*std::ops::Deref::deref_mut(&mut
775+
[immutable lvalue context](#mutability) and `*std::ops::Deref::deref_mut(&mut
763776
x)` in a mutable lvalue context.
764777

765778
```rust
@@ -793,11 +806,11 @@ println!("{:?}", res);
793806

794807
### Negation operators
795808

796-
This table summarizes the behavior of the last two unary operators on
797-
primitive types and which traits are used to overload these operators for other
798-
types. Remember that signed integers are always represented using two's
799-
complement. The operands of all of these operators are evaluated in rvalue
800-
context and are moved or copied.
809+
These are the last two unary operators. This table summarizes the behavior of
810+
them on primitive types and which traits are used to overload these operators
811+
for other types. Remember that signed integers are always represented using
812+
two's complement. The operands of all of these operators are evaluated in
813+
rvalue context so are moved or copied.
801814

802815
| Symbol | Integer | `bool` | Floating Point | Overloading Trait |
803816
|--------|-------------|-------------|----------------|--------------------|
@@ -822,7 +835,7 @@ summarizes the behavior of arithmetic and logical binary operators on
822835
primitive types and which traits are used to overload these operators for other
823836
types. Remember that signed integers are always represented using two's
824837
complement. The operands of all of these operators are evaluated in rvalue
825-
context and are moved or copied.
838+
context so are moved or copied.
826839

827840
| Symbol | Integer | `bool` | Floating Point | Overloading Trait |
828841
|--------|-------------------------|-------------|----------------|--------------------|
@@ -934,8 +947,8 @@ fn average(values: &[f64]) -> f64 {
934947
```
935948

936949
`as` can be used to explicitly perform [coercions](type-coercions.html), as
937-
well as the following additional casts. `*T` is short for either
938-
`*const T` or `*mut T`.
950+
well as the following additional casts. Here `*T` means either `*const T` or
951+
`*mut T`.
939952

940953
| Type of `e` | `U` | Cast performed by `e as U` |
941954
|-----------------------|-----------------------|----------------------------------|
@@ -950,7 +963,10 @@ well as the following additional casts. `*T` is short for either
950963
| [Function pointer](type.html#function-types) | `*V` where `V: Sized` | Function pointer to pointer cast |
951964
| Function pointer | Integer | Function pointer to address cast |
952965

953-
\* or `T` and `V` are compatible unsized types, e.g., both slices.
966+
\* or `T` and `V` are compatible unsized types, e.g., both slices, both the
967+
same trait object.
968+
969+
#### Semantics
954970

955971
* Numeric cast
956972
* Casting between two integers of the same size (e.g. i32 -> u32) is a no-op
@@ -1041,7 +1057,7 @@ given by their associativity.
10411057
| <code>&#124;&#124;</code> | left to right |
10421058
| `..` `...` | Require parentheses |
10431059
| `<-` | right to left |
1044-
| `=` `+=` `-=` `*=` `/=` `%=` `&=` <code>&#124;=</code> `^=` `<<=` `>>=` | right to left |
1060+
| `=` `+=` `-=` `*=` `/=` `%=` <br> `&=` <code>&#124;=</code> `^=` `<<=` `>>=` | right to left |
10451061

10461062
## Grouped expressions
10471063

@@ -1402,7 +1418,7 @@ condition expression it expects the keyword `let` followed by a refutable
14021418
pattern, an `=` and an expression. If the value of the expression on the right
14031419
hand side of the `=` matches the pattern, the loop body block executes then
14041420
control returns to the pattern matching statement. Otherwise, the while
1405-
expression completes. Like `while` loops, `while let` loops evaluate to `()`.
1421+
expression completes.
14061422

14071423
```rust
14081424
let mut x = vec![1, 2, 3];

0 commit comments

Comments
 (0)