Skip to content

Document that unary negation of a signed integer literal cannot cause an overflow error #1188

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

Merged
merged 1 commit into from
Apr 7, 2022
Merged
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
2 changes: 2 additions & 0 deletions src/expressions/literal-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ If the value does not fit in `u128`, the expression is rejected by the parser.
> `rustc` includes a [lint check] named `overflowing_literals`, defaulting to `deny`, which rejects expressions where this occurs.

> **Note**: `-1i8`, for example, is an application of the [negation operator] to the literal expression `1i8`, not a single integer literal expression.
> See [Overflow] for notes on representing the most negative value for a signed type.

## Floating-point literal expressions

Expand Down Expand Up @@ -159,6 +160,7 @@ A boolean literal expression consists of a single [BOOLEAN_LITERAL] token.
[numeric types]: ../types/numeric.md
[suffix]: ../tokens.md#suffixes
[negation operator]: operator-expr.md#negation-operators
[overflow]: operator-expr.md#overflow
[`f32::from_str`]: ../../core/primitive.f32.md#method.from_str
[`f32::INFINITY`]: ../../core/primitive.f32.md#associatedconstant.INFINITY
[`f32::NAN`]: ../../core/primitive.f32.md#associatedconstant.NAN
Expand Down
14 changes: 12 additions & 2 deletions src/expressions/operator-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,20 @@ Integer operators will panic when they overflow when compiled in debug mode.
The `-C debug-assertions` and `-C overflow-checks` compiler flags can be used to control this more directly.
The following things are considered to be overflow:

* When `+`, `*` or `-` create a value greater than the maximum value, or less than the minimum value that can be stored.
This includes unary `-` on the smallest value of any signed integer type.
* When `+`, `*` or binary `-` create a value greater than the maximum value, or less than the minimum value that can be stored.
* 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]).
* Using `/` or `%`, where the left-hand argument is the smallest integer of a signed integer type and the right-hand argument is `-1`.
These checks occur even when `-C overflow-checks` is disabled, for legacy reasons.
* 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.

> **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.
>
> 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].
>
> Negation of these most negative values leaves the value unchanged due to two's complement overflow conventions.
>
> In `rustc`, these most negative expressions are also ignored by the `overflowing_literals` lint check.

## Borrow operators

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

[copies or moves]: ../expressions.md#moved-and-copied-types
[dropping]: ../destructors.md
[grouped expression]: grouped-expr.md
[literal expression]: literal-expr.md#integer-literal-expressions
[logical and]: ../types/boolean.md#logical-and
[logical not]: ../types/boolean.md#logical-not
[logical or]: ../types/boolean.md#logical-or
Expand Down