]> git.proxmox.com Git - rustc.git/blame - src/doc/reference/src/expressions/operator-expr.md
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / src / doc / reference / src / expressions / operator-expr.md
CommitLineData
ea8adc8c
XL
1# Operator expressions
2
8faf50e0
XL
3> **<sup>Syntax</sup>**\
4> _OperatorExpression_ :\
5> &nbsp;&nbsp; &nbsp;&nbsp; [_BorrowExpression_]\
6> &nbsp;&nbsp; | [_DereferenceExpression_]\
7> &nbsp;&nbsp; | [_ErrorPropagationExpression_]\
8> &nbsp;&nbsp; | [_NegationExpression_]\
9> &nbsp;&nbsp; | [_ArithmeticOrLogicalExpression_]\
10> &nbsp;&nbsp; | [_ComparisonExpression_]\
11> &nbsp;&nbsp; | [_LazyBooleanExpression_]\
12> &nbsp;&nbsp; | [_TypeCastExpression_]\
13> &nbsp;&nbsp; | [_AssignmentExpression_]\
14> &nbsp;&nbsp; | [_CompoundAssignmentExpression_]
0531ce1d 15
6a06907d
XL
16Operators are defined for built in types by the Rust language.
17Many of the following operators can also be overloaded using traits in `std::ops` or `std::cmp`.
ea8adc8c
XL
18
19## Overflow
20
21Integer operators will panic when they overflow when compiled in debug mode.
6a06907d
XL
22The `-C debug-assertions` and `-C overflow-checks` compiler flags can be used to control this more directly.
23The following things are considered to be overflow:
24
25* When `+`, `*` or `-` create a value greater than the maximum value, or less than the minimum value that can be stored.
26 This includes unary `-` on the smallest value of any signed integer type.
27* Using `/` or `%`, where the left-hand argument is the smallest integer of a signed integer type and the right-hand argument is `-1`.
28* Using `<<` or `>>` where the right-hand argument is greater than or equal to the number of bits in the type of the left-hand argument, or is negative.
ea8adc8c 29
ea8adc8c
XL
30## Borrow operators
31
8faf50e0
XL
32> **<sup>Syntax</sup>**\
33> _BorrowExpression_ :\
34> &nbsp;&nbsp; &nbsp;&nbsp; (`&`|`&&`) [_Expression_]\
35> &nbsp;&nbsp; | (`&`|`&&`) `mut` [_Expression_]
0531ce1d 36
6a06907d
XL
37The `&` (shared borrow) and `&mut` (mutable borrow) operators are unary prefix operators.
38When applied to a [place expression], this expressions produces a reference (pointer) to the location that the value refers to.
39The memory location is also placed into a borrowed state for the duration of the reference.
40For a shared borrow (`&`), this implies that the place may not be mutated, but it may be read or shared again.
41For a mutable borrow (`&mut`), the place may not be accessed in any way until the borrow expires.
42`&mut` evaluates its operand in a mutable place expression context.
43If the `&` or `&mut` operators are applied to a [value expression], then a [temporary value] is created.
ff7c6d11
XL
44
45These operators cannot be overloaded.
ea8adc8c
XL
46
47```rust
48{
49 // a temporary with value 7 is created that lasts for this scope.
50 let shared_reference = &7;
51}
52let mut array = [-2, 3, 9];
53{
54 // Mutably borrows `array` for this scope.
55 // `array` may only be used through `mutable_reference`.
56 let mutable_reference = &mut array;
57}
58```
59
6a06907d 60Even though `&&` is a single token ([the lazy 'and' operator](#lazy-boolean-operators)), when used in the context of borrow expressions it works as two borrows:
0531ce1d
XL
61
62```rust
63// same meanings:
64let a = && 10;
65let a = & & 10;
66
67// same meanings:
68let a = &&&& mut 10;
69let a = && && mut 10;
70let a = & & & & mut 10;
71```
72
ea8adc8c
XL
73## The dereference operator
74
8faf50e0
XL
75> **<sup>Syntax</sup>**\
76> _DereferenceExpression_ :\
0531ce1d
XL
77> &nbsp;&nbsp; `*` [_Expression_]
78
6a06907d
XL
79The `*` (dereference) operator is also a unary prefix operator.
80When applied to a [pointer](../types/pointer.md) it denotes the pointed-to location.
81If the expression is of type `&mut T` or `*mut T`, and is either a local variable, a (nested) field of a local variable or is a mutable [place expression], then the resulting memory location can be assigned to.
ff7c6d11 82Dereferencing a raw pointer requires `unsafe`.
ea8adc8c 83
6a06907d 84On non-pointer types `*x` is equivalent to `*std::ops::Deref::deref(&x)` in an [immutable place expression context](../expressions.md#mutability) and `*std::ops::DerefMut::deref_mut(&mut x)` in a mutable place expression context.
ea8adc8c
XL
85
86```rust
87let x = &7;
88assert_eq!(*x, 7);
89let y = &mut 9;
90*y = 11;
91assert_eq!(*y, 11);
92```
93
ff7c6d11
XL
94## The question mark operator
95
8faf50e0
XL
96> **<sup>Syntax</sup>**\
97> _ErrorPropagationExpression_ :\
98> &nbsp;&nbsp; [_Expression_] `?`
0531ce1d 99
6a06907d
XL
100The question mark operator (`?`) unwraps valid values or returns erroneous values, propagating them to the calling function.
101It is a unary postfix operator that can only be applied to the types `Result<T, E>` and `Option<T>`.
ea8adc8c 102
6a06907d
XL
103When applied to values of the `Result<T, E>` type, it propagates errors.
104If the value is `Err(e)`, then it will return `Err(From::from(e))` from the enclosing function or closure.
105If applied to `Ok(x)`, then it will unwrap the value to evaluate to `x`.
ea8adc8c
XL
106
107```rust
108# use std::num::ParseIntError;
109fn try_to_parse() -> Result<i32, ParseIntError> {
110 let x: i32 = "123".parse()?; // x = 123
111 let y: i32 = "24a".parse()?; // returns an Err() immediately
112 Ok(x + y) // Doesn't run.
113}
114
115let res = try_to_parse();
116println!("{:?}", res);
117# assert!(res.is_err())
118```
119
6a06907d
XL
120When applied to values of the `Option<T>` type, it propagates `None`s.
121If the value is `None`, then it will return `None`.
122If applied to `Some(x)`, then it will unwrap the value to evaluate to `x`.
ff7c6d11
XL
123
124```rust
125fn try_option_some() -> Option<u8> {
126 let val = Some(1)?;
127 Some(val)
128}
129assert_eq!(try_option_some(), Some(1));
130
131fn try_option_none() -> Option<u8> {
132 let val = None?;
133 Some(val)
134}
135assert_eq!(try_option_none(), None);
136```
137
138`?` cannot be overloaded.
139
ea8adc8c
XL
140## Negation operators
141
8faf50e0
XL
142> **<sup>Syntax</sup>**\
143> _NegationExpression_ :\
144> &nbsp;&nbsp; &nbsp;&nbsp; `-` [_Expression_]\
145> &nbsp;&nbsp; | `!` [_Expression_]
0531ce1d 146
6a06907d
XL
147These are the last two unary operators.
148This table summarizes the behavior of them on primitive types and which traits are used to overload these operators for other types.
149Remember that signed integers are always represented using two's complement.
150The operands of all of these operators are evaluated in [value expression context][value expression] so are moved or copied.
ea8adc8c 151
6a06907d
XL
152| Symbol | Integer | `bool` | Floating Point | Overloading Trait |
153|--------|-------------|-------------- |----------------|--------------------|
154| `-` | Negation* | | Negation | `std::ops::Neg` |
155| `!` | Bitwise NOT | [Logical NOT] | | `std::ops::Not` |
ea8adc8c
XL
156
157\* Only for signed integer types.
158
159Here are some example of these operators
160
161```rust
162let x = 6;
163assert_eq!(-x, -6);
164assert_eq!(!x, -7);
165assert_eq!(true, !false);
166```
167
168## Arithmetic and Logical Binary Operators
169
8faf50e0
XL
170> **<sup>Syntax</sup>**\
171> _ArithmeticOrLogicalExpression_ :\
172> &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] `+` [_Expression_]\
173> &nbsp;&nbsp; | [_Expression_] `-` [_Expression_]\
174> &nbsp;&nbsp; | [_Expression_] `*` [_Expression_]\
175> &nbsp;&nbsp; | [_Expression_] `/` [_Expression_]\
176> &nbsp;&nbsp; | [_Expression_] `%` [_Expression_]\
177> &nbsp;&nbsp; | [_Expression_] `&` [_Expression_]\
178> &nbsp;&nbsp; | [_Expression_] `|` [_Expression_]\
179> &nbsp;&nbsp; | [_Expression_] `^` [_Expression_]\
180> &nbsp;&nbsp; | [_Expression_] `<<` [_Expression_]\
181> &nbsp;&nbsp; | [_Expression_] `>>` [_Expression_]
0531ce1d 182
6a06907d
XL
183Binary operators expressions are all written with infix notation.
184This table summarizes the behavior of arithmetic and logical binary operators on primitive types and which traits are used to overload these operators for other types.
185Remember that signed integers are always represented using two's complement.
186The operands of all of these operators are evaluated in [value expression context][value expression] so are moved or copied.
187
188| Symbol | Integer | `bool` | Floating Point | Overloading Trait | Overloading Compound Assignment Trait |
189|--------|-------------------------|---------------|----------------|--------------------| ------------------------------------- |
190| `+` | Addition | | Addition | `std::ops::Add` | `std::ops::AddAssign` |
191| `-` | Subtraction | | Subtraction | `std::ops::Sub` | `std::ops::SubAssign` |
192| `*` | Multiplication | | Multiplication | `std::ops::Mul` | `std::ops::MulAssign` |
193| `/` | Division* | | Division | `std::ops::Div` | `std::ops::DivAssign` |
194| `%` | Remainder | | Remainder | `std::ops::Rem` | `std::ops::RemAssign` |
195| `&` | Bitwise AND | [Logical AND] | | `std::ops::BitAnd` | `std::ops::BitAndAssign` |
196| <code>&#124;</code> | Bitwise OR | [Logical OR] | | `std::ops::BitOr` | `std::ops::BitOrAssign` |
197| `^` | Bitwise XOR | [Logical XOR] | | `std::ops::BitXor` | `std::ops::BitXorAssign` |
198| `<<` | Left Shift | | | `std::ops::Shl` | `std::ops::ShlAssign` |
199| `>>` | Right Shift** | | | `std::ops::Shr` | `std::ops::ShrAssign` |
ea8adc8c 200
94b46f34
XL
201\* Integer division rounds towards zero.
202
203\*\* Arithmetic right shift on signed integer types, logical right shift on
ea8adc8c
XL
204unsigned integer types.
205
206Here are examples of these operators being used.
207
208```rust
209assert_eq!(3 + 6, 9);
210assert_eq!(5.5 - 1.25, 4.25);
211assert_eq!(-5 * 14, -70);
212assert_eq!(14 / 3, 4);
213assert_eq!(100 % 7, 2);
214assert_eq!(0b1010 & 0b1100, 0b1000);
215assert_eq!(0b1010 | 0b1100, 0b1110);
216assert_eq!(0b1010 ^ 0b1100, 0b110);
217assert_eq!(13 << 3, 104);
218assert_eq!(-10 >> 2, -3);
219```
220
221## Comparison Operators
222
8faf50e0
XL
223> **<sup>Syntax</sup>**\
224> _ComparisonExpression_ :\
225> &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] `==` [_Expression_]\
226> &nbsp;&nbsp; | [_Expression_] `!=` [_Expression_]\
227> &nbsp;&nbsp; | [_Expression_] `>` [_Expression_]\
228> &nbsp;&nbsp; | [_Expression_] `<` [_Expression_]\
229> &nbsp;&nbsp; | [_Expression_] `>=` [_Expression_]\
230> &nbsp;&nbsp; | [_Expression_] `<=` [_Expression_]
0531ce1d 231
6a06907d
XL
232Comparison operators are also defined both for primitive types and many types in the standard library.
233Parentheses are required when chaining comparison operators. For example, the expression `a == b == c` is invalid and may be written as `(a == b) == c`.
ea8adc8c 234
6a06907d
XL
235Unlike arithmetic and logical operators, the traits for overloading these operators are used more generally to show how a type may be compared and will likely be assumed to define actual comparisons by functions that use these traits as bounds.
236Many functions and macros in the standard library can then use that assumption (although not to ensure safety).
237Unlike the arithmetic and logical operators above, these operators implicitly take shared borrows of their operands, evaluating them in [place expression context][place expression]:
ea8adc8c 238
60c5eb7d
XL
239```rust
240# let a = 1;
241# let b = 1;
ea8adc8c
XL
242a == b;
243// is equivalent to
244::std::cmp::PartialEq::eq(&a, &b);
245```
246
247This means that the operands don't have to be moved out of.
248
249| Symbol | Meaning | Overloading method |
250|--------|--------------------------|----------------------------|
251| `==` | Equal | `std::cmp::PartialEq::eq` |
252| `!=` | Not equal | `std::cmp::PartialEq::ne` |
253| `>` | Greater than | `std::cmp::PartialOrd::gt` |
254| `<` | Less than | `std::cmp::PartialOrd::lt` |
255| `>=` | Greater than or equal to | `std::cmp::PartialOrd::ge` |
256| `<=` | Less than or equal to | `std::cmp::PartialOrd::le` |
257
258Here are examples of the comparison operators being used.
259
260```rust
261assert!(123 == 123);
262assert!(23 != -12);
263assert!(12.5 > 12.2);
264assert!([1, 2, 3] < [1, 3, 4]);
265assert!('A' <= 'B');
266assert!("World" >= "Hello");
267```
268
269## Lazy boolean operators
270
8faf50e0
XL
271> **<sup>Syntax</sup>**\
272> _LazyBooleanExpression_ :\
273> &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] `||` [_Expression_]\
0531ce1d
XL
274> &nbsp;&nbsp; | [_Expression_] `&&` [_Expression_]
275
6a06907d
XL
276The operators `||` and `&&` may be applied to operands of boolean type.
277The `||` operator denotes logical 'or', and the `&&` operator denotes logical 'and'.
278They differ from `|` and `&` in that the right-hand operand is only evaluated when the left-hand operand does not already determine the result of the expression.
279That is, `||` only evaluates its right-hand operand when the left-hand operand evaluates to `false`, and `&&` only when it evaluates to `true`.
ea8adc8c
XL
280
281```rust
282let x = false || true; // true
283let y = false && panic!(); // false, doesn't evaluate `panic!()`
284```
285
286## Type cast expressions
287
8faf50e0
XL
288> **<sup>Syntax</sup>**\
289> _TypeCastExpression_ :\
0bf4aa26 290> &nbsp;&nbsp; [_Expression_] `as` [_TypeNoBounds_]
0531ce1d 291
ea8adc8c
XL
292A type cast expression is denoted with the binary operator `as`.
293
6a06907d 294Executing an `as` expression casts the value on the left-hand side to the type on the right-hand side.
ea8adc8c
XL
295
296An example of an `as` expression:
297
298```rust
299# fn sum(values: &[f64]) -> f64 { 0.0 }
300# fn len(values: &[f64]) -> i32 { 0 }
301fn average(values: &[f64]) -> f64 {
302 let sum: f64 = sum(values);
303 let size: f64 = len(values) as f64;
304 sum / size
305}
306```
307
6a06907d
XL
308`as` can be used to explicitly perform [coercions](../type-coercions.md), as well as the following additional casts.
309Here `*T` means either `*const T` or `*mut T`.
ea8adc8c
XL
310
311| Type of `e` | `U` | Cast performed by `e as U` |
312|-----------------------|-----------------------|----------------------------------|
313| Integer or Float type | Integer or Float type | Numeric cast |
314| C-like enum | Integer type | Enum cast |
315| `bool` or `char` | Integer type | Primitive to integer cast |
316| `u8` | `char` | `u8` to `char` cast |
317| `*T` | `*V` where `V: Sized` \* | Pointer to pointer cast |
6a06907d 318| `*T` where `T: Sized` | Integer type | Pointer to address cast |
ea8adc8c
XL
319| Integer type | `*V` where `V: Sized` | Address to pointer cast |
320| `&[T; n]` | `*const T` | Array to pointer cast |
3dfed10e
XL
321| [Function item] | [Function pointer] | Function item to function pointer cast |
322| [Function item] | `*V` where `V: Sized` | Function item to pointer cast |
323| [Function item] | Integer | Function item to address cast |
324| [Function pointer] | `*V` where `V: Sized` | Function pointer to pointer cast |
325| [Function pointer] | Integer | Function pointer to address cast |
94b46f34 326| Closure \*\* | Function pointer | Closure to function pointer cast |
ea8adc8c 327
6a06907d 328\* or `T` and `V` are compatible unsized types, e.g., both slices, both the same trait object.
ea8adc8c 329
532ac7d7 330\*\* only for closures that do not capture (close over) any local variables
94b46f34 331
ea8adc8c
XL
332### Semantics
333
334* Numeric cast
335 * Casting between two integers of the same size (e.g. i32 -> u32) is a no-op
336 * Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will
337 truncate
338 * Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
339 * zero-extend if the source is unsigned
340 * sign-extend if the source is signed
341 * Casting from a float to an integer will round the float towards zero
f9f354fc
XL
342 * `NaN` will return `0`
343 * Values larger than the maximum integer value will saturate to the
344 maximum value of the integer type.
345 * Values smaller than the minimum integer value will saturate to the
346 minimum value of the integer type.
e1599b0c
XL
347 * Casting from an integer to float will produce the closest possible float \*
348 * if necessary, rounding is according to `roundTiesToEven` mode \*\*\*
349 * on overflow, infinity (of the same sign as the input) is produced
350 * note: with the current set of numeric types, overflow can only happen
351 on `u128 as f32` for values greater or equal to `f32::MAX + (0.5 ULP)`
ea8adc8c 352 * Casting from an f32 to an f64 is perfect and lossless
e1599b0c
XL
353 * Casting from an f64 to an f32 will produce the closest possible f32 \*\*
354 * if necessary, rounding is according to `roundTiesToEven` mode \*\*\*
355 * on overflow, infinity (of the same sign as the input) is produced
ea8adc8c
XL
356* Enum cast
357 * Casts an enum to its discriminant, then uses a numeric cast if needed.
358* Primitive to integer cast
359 * `false` casts to `0`, `true` casts to `1`
360 * `char` casts to the value of the code point, then uses a numeric cast if needed.
361* `u8` to `char` cast
362 * Casts to the `char` with the corresponding code point.
363
e1599b0c
XL
364\* if integer-to-float casts with this rounding mode and overflow behavior are
365not supported natively by the hardware, these casts will likely be slower than
366expected.
367
368\*\* if f64-to-f32 casts with this rounding mode and overflow behavior are not
369supported natively by the hardware, these casts will likely be slower than
370expected.
371
372\*\*\* as defined in IEEE 754-2008 &sect;4.3.1: pick the nearest floating point
373number, preferring the one with an even least significant digit if exactly
374halfway between two floating point numbers.
375
ea8adc8c
XL
376## Assignment expressions
377
8faf50e0
XL
378> **<sup>Syntax</sup>**\
379> _AssignmentExpression_ :\
48663c56 380> &nbsp;&nbsp; [_Expression_] `=` [_Expression_]
0531ce1d 381
5869c6ff 382An *assignment expression* moves a value into a specified place.
ea8adc8c 383
6a06907d 384An assignment expression consists of a [mutable] [place expression], the *assigned place operand*, followed by an equals sign (`=`) and a [value expression], the *assigned value operand*.
5869c6ff 385
6a06907d
XL
386Unlike other place operands, the assigned place operand must be a place expression.
387Attempting to use a value expression is a compiler error rather than promoting it to a temporary.
ea8adc8c 388
6a06907d
XL
389Evaluating assignment expressions begins by evaluating its operands.
390The assigned value operand is evaluated first, followed by the assigned place operand.
5869c6ff 391
6a06907d 392> **Note**: This is different than other expressions in that the right operand is evaluated before the left one.
5869c6ff 393
6a06907d
XL
394It then has the effect of first [dropping] the value at the assigned place, unless the place is an uninitialized local variable or an uninitialized field of a local variable.
395Next it either [copies or moves] the assigned value to the assigned place.
5869c6ff
XL
396
397An assignment expression always produces [the unit value][unit].
398
399Example:
400
ea8adc8c 401```rust
5869c6ff
XL
402let mut x = 0;
403let y = 0;
ea8adc8c
XL
404x = y;
405```
406
407## Compound assignment expressions
408
8faf50e0
XL
409> **<sup>Syntax</sup>**\
410> _CompoundAssignmentExpression_ :\
411> &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] `+=` [_Expression_]\
412> &nbsp;&nbsp; | [_Expression_] `-=` [_Expression_]\
413> &nbsp;&nbsp; | [_Expression_] `*=` [_Expression_]\
414> &nbsp;&nbsp; | [_Expression_] `/=` [_Expression_]\
415> &nbsp;&nbsp; | [_Expression_] `%=` [_Expression_]\
416> &nbsp;&nbsp; | [_Expression_] `&=` [_Expression_]\
417> &nbsp;&nbsp; | [_Expression_] `|=` [_Expression_]\
418> &nbsp;&nbsp; | [_Expression_] `^=` [_Expression_]\
419> &nbsp;&nbsp; | [_Expression_] `<<=` [_Expression_]\
420> &nbsp;&nbsp; | [_Expression_] `>>=` [_Expression_]
0531ce1d 421
6a06907d 422*Compound assignment expressions* combine arithmetic and logical binary operators with assignment expressions.
5869c6ff
XL
423
424For example:
425
426```rust
427let mut x = 5;
428x += 1;
429assert!(x == 6);
430```
431
6a06907d 432The syntax of compound assignment is a [mutable] [place expression], the *assigned operand*, then one of the operators followed by an `=` as a single token (no whitespace), and then a [value expression], the *modifying operand*.
5869c6ff 433
6a06907d
XL
434Unlike other place operands, the assigned place operand must be a place expression.
435Attempting to use a value expression is a compiler error rather than promoting it to a temporary.
5869c6ff 436
6a06907d 437Evaluation of compound assignment expressions depends on the types of the operators.
5869c6ff 438
6a06907d
XL
439If both types are primitives, then the modifying operand will be evaluated first followed by the assigned operand.
440It will then set the value of the assigned operand's place to the value of performing the operation of the operator with the values of the assigned operand and modifying operand.
5869c6ff 441
6a06907d 442> **Note**: This is different than other expressions in that the right operand is evaluated before the left one.
5869c6ff 443
6a06907d
XL
444Otherwise, this expression is syntactic sugar for calling the function of the overloading compound assigment trait of the operator (see the table earlier in this chapter).
445A mutable borrow of the assigned operand is automatically taken.
5869c6ff
XL
446
447For example, the following expression statements in `example` are equivalent:
ea8adc8c
XL
448
449```rust
5869c6ff
XL
450# struct Addable;
451# use std::ops::AddAssign;
452
453impl AddAssign<Addable> for Addable {
454 /* */
455# fn add_assign(&mut self, other: Addable) {}
456}
457
458fn example() {
459# let (mut a1, a2) = (Addable, Addable);
460 a1 += a2;
461
462# let (mut a1, a2) = (Addable, Addable);
463 AddAssign::add_assign(&mut a1, a2);
464}
ea8adc8c 465```
ff7c6d11 466
5869c6ff
XL
467<div class="warning">
468
6a06907d
XL
469Warning: The evaluation order of operands swaps depending on the types of the operands:
470with primitive types the right-hand side will get evaluated first, while with non-primitive types the left-hand side will get evaluated first.
471Try not to write code that depends on the evaluation order of operands in compound assignment expressions.
472See [this test] for an example of using this dependency.
5869c6ff
XL
473
474</div>
475
476[copies or moves]: ../expressions.md#moved-and-copied-types
477[dropping]: ../destructors.md
6a06907d
XL
478[logical and]: ../types/boolean.md#logical-and
479[logical not]: ../types/boolean.md#logical-not
480[logical or]: ../types/boolean.md#logical-or
481[logical xor]: ../types/boolean.md#logical-xor
5869c6ff 482[mutable]: ../expressions.md#mutability
416331ca 483[place expression]: ../expressions.md#place-expressions-and-value-expressions
5869c6ff 484[unit]: ../types/tuple.md
416331ca 485[value expression]: ../expressions.md#place-expressions-and-value-expressions
f9f354fc 486[temporary value]: ../expressions.md#temporaries
5869c6ff 487[this test]: https://github.com/rust-lang/rust/blob/master/src/test/ui/expr/compound-assignment/eval-order.rs
ff7c6d11 488[float-float]: https://github.com/rust-lang/rust/issues/15536
3dfed10e
XL
489[Function pointer]: ../types/function-pointer.md
490[Function item]: ../types/function-item.md
0531ce1d
XL
491
492[_BorrowExpression_]: #borrow-operators
493[_DereferenceExpression_]: #the-dereference-operator
494[_ErrorPropagationExpression_]: #the-question-mark-operator
495[_NegationExpression_]: #negation-operators
496[_ArithmeticOrLogicalExpression_]: #arithmetic-and-logical-binary-operators
497[_ComparisonExpression_]: #comparison-operators
498[_LazyBooleanExpression_]: #lazy-boolean-operators
499[_TypeCastExpression_]: #type-cast-expressions
500[_AssignmentExpression_]: #assignment-expressions
501[_CompoundAssignmentExpression_]: #compound-assignment-expressions
502
416331ca
XL
503[_Expression_]: ../expressions.md
504[_TypeNoBounds_]: ../types.md#type-expressions