Skip to content

Commit 60e99b1

Browse files
authored
Merge pull request #1188 from mattheww/2022-04_negation_overflow
Document that unary negation of a signed integer literal cannot cause an overflow error
2 parents 41e5c78 + 89a81e8 commit 60e99b1

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

src/expressions/literal-expr.md

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ If the value does not fit in `u128`, the expression is rejected by the parser.
107107
> `rustc` includes a [lint check] named `overflowing_literals`, defaulting to `deny`, which rejects expressions where this occurs.
108108
109109
> **Note**: `-1i8`, for example, is an application of the [negation operator] to the literal expression `1i8`, not a single integer literal expression.
110+
> See [Overflow] for notes on representing the most negative value for a signed type.
110111
111112
## Floating-point literal expressions
112113

@@ -159,6 +160,7 @@ A boolean literal expression consists of a single [BOOLEAN_LITERAL] token.
159160
[numeric types]: ../types/numeric.md
160161
[suffix]: ../tokens.md#suffixes
161162
[negation operator]: operator-expr.md#negation-operators
163+
[overflow]: operator-expr.md#overflow
162164
[`f32::from_str`]: ../../core/primitive.f32.md#method.from_str
163165
[`f32::INFINITY`]: ../../core/primitive.f32.md#associatedconstant.INFINITY
164166
[`f32::NAN`]: ../../core/primitive.f32.md#associatedconstant.NAN

src/expressions/operator-expr.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,20 @@ Integer operators will panic when they overflow when compiled in debug mode.
2222
The `-C debug-assertions` and `-C overflow-checks` compiler flags can be used to control this more directly.
2323
The following things are considered to be overflow:
2424

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.
25+
* When `+`, `*` or binary `-` create a value greater than the maximum value, or less than the minimum value that can be stored.
26+
* Applying unary `-` to the most negative value of any signed integer type, unless the operand is a [literal expression] (or a literal expression standing alone inside one or more [grouped expressions][grouped expression]).
2727
* Using `/` or `%`, where the left-hand argument is the smallest integer of a signed integer type and the right-hand argument is `-1`.
2828
These checks occur even when `-C overflow-checks` is disabled, for legacy reasons.
2929
* 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.
3030

31+
> **Note**: The exception for literal expressions behind unary `-` means that forms such as `-128_i8` or `let j: i8 = -(128)` never cause a panic and have the expected value of -128.
32+
>
33+
> In these cases, the literal expression already has the most negative value for its type (for example, `128_i8` has the value -128) because integer literals are truncated to their type per the description in [Integer literal expressions][literal expression].
34+
>
35+
> Negation of these most negative values leaves the value unchanged due to two's complement overflow conventions.
36+
>
37+
> In `rustc`, these most negative expressions are also ignored by the `overflowing_literals` lint check.
38+
3139
## Borrow operators
3240

3341
> **<sup>Syntax</sup>**\
@@ -580,6 +588,8 @@ See [this test] for an example of using this dependency.
580588

581589
[copies or moves]: ../expressions.md#moved-and-copied-types
582590
[dropping]: ../destructors.md
591+
[grouped expression]: grouped-expr.md
592+
[literal expression]: literal-expr.md#integer-literal-expressions
583593
[logical and]: ../types/boolean.md#logical-and
584594
[logical not]: ../types/boolean.md#logical-not
585595
[logical or]: ../types/boolean.md#logical-or

0 commit comments

Comments
 (0)