Skip to content

Commit

Permalink
Merge pull request #940 from Havvy/bool
Browse files Browse the repository at this point in the history
Referencify bool type
  • Loading branch information
ehuss authored Feb 8, 2021
2 parents 64ef976 + 1804726 commit 5037683
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 47 deletions.
5 changes: 3 additions & 2 deletions src/behavior-considered-undefined.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ code.
a function/primitive operation or returned from a function/primitive
operation.
The following values are invalid (at their respective type):
* A value other than `false` (`0`) or `true` (`1`) in a `bool`.
* A value other than `false` (`0`) or `true` (`1`) in a [`bool`].
* A discriminant in an `enum` not included in the type definition.
* A null `fn` pointer.
* A value in a `char` which is a surrogate or above `char::MAX`.
Expand Down Expand Up @@ -77,7 +77,8 @@ cannot be bigger than `isize::MAX` bytes.
> vice versa, undefined behavior in Rust can cause adverse affects on code
> executed by any FFI calls to other languages.
[`const`]: items/constant-items.html
[`bool`]: types/boolean.md
[`const`]: items/constant-items.md
[noalias]: http://llvm.org/docs/LangRef.html#noalias
[pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules
[undef]: http://llvm.org/docs/LangRef.html#undefined-values
Expand Down
15 changes: 8 additions & 7 deletions src/expressions/if-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
> | _IfExpression_
> | _IfLetExpression_ ) )<sup>\?</sup>
An `if` expression is a conditional branch in program control. The form of an
`if` expression is a condition expression, followed by a consequent block, any
An `if` expression is a conditional branch in program control. The syntax of an
`if` expression is a condition operand, followed by a consequent block, any
number of `else if` conditions and blocks, and an optional trailing `else`
block. The condition expressions must have type `bool`. If a condition
expression evaluates to `true`, the consequent block is executed and any
subsequent `else if` or `else` block is skipped. If a condition expression
block. The condition operands must have the [boolean type]. If a condition
operand evaluates to `true`, the consequent block is executed and any
subsequent `else if` or `else` block is skipped. If a condition operand
evaluates to `false`, the consequent block is skipped and any subsequent `else
if` condition is evaluated. If all `if` and `else if` conditions evaluate to
`false` then any `else` block is executed. An if expression evaluates to the
Expand Down Expand Up @@ -52,8 +52,8 @@ assert_eq!(y, "Bigger");
> | _IfLetExpression_ ) )<sup>\?</sup>
An `if let` expression is semantically similar to an `if` expression but in
place of a condition expression it expects the keyword `let` followed by a
pattern, an `=` and a [scrutinee] expression. If the value of the scrutinee
place of a condition operand it expects the keyword `let` followed by a
pattern, an `=` and a [scrutinee] operand. If the value of the scrutinee
matches the pattern, the corresponding block will execute. Otherwise, flow
proceeds to the following `else` block if it exists. Like `if` expressions,
`if let` expressions have a value determined by the block that is evaluated.
Expand Down Expand Up @@ -158,4 +158,5 @@ if let PAT = ( EXPR || EXPR ) { .. }
[_MatchArmPatterns_]: match-expr.md
[_eRFCIfLetChain_]: https://github.com/rust-lang/rfcs/blob/master/text/2497-if-let-chains.md#rollout-plan-and-transitioning-to-rust-2018
[`match` expression]: match-expr.md
[boolean type]: ../types/boolean.md
[scrutinee]: ../glossary.md#scrutinee
7 changes: 4 additions & 3 deletions src/expressions/loop-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ have type compatible with the value of the `break` expression(s).
> _PredicateLoopExpression_ :\
> &nbsp;&nbsp; `while` [_Expression_]<sub>_except struct expression_</sub> [_BlockExpression_]
A `while` loop begins by evaluating the boolean loop conditional expression. If
the loop conditional expression evaluates to `true`, the loop body block
executes, then control returns to the loop conditional expression. If the loop
A `while` loop begins by evaluating the [boolean] loop conditional operand. If
the loop conditional operand evaluates to `true`, the loop body block
executes, then control returns to the loop conditional operand. If the loop
conditional expression evaluates to `false`, the `while` expression completes.

An example:
Expand Down Expand Up @@ -294,6 +294,7 @@ expression `()`.
[_MatchArmPatterns_]: match-expr.md
[_Pattern_]: ../patterns.md
[`match` expression]: match-expr.md
[boolean]: ../types/boolean.md
[scrutinee]: ../glossary.md#scrutinee
[temporary values]: ../expressions.md#temporaries
[_LazyBooleanOperatorExpression_]: operator-expr.md#lazy-boolean-operators
Expand Down
36 changes: 20 additions & 16 deletions src/expressions/operator-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ for other types. Remember that signed integers are always represented using
two's complement. The operands of all of these operators are evaluated in
[value expression context][value expression] so are moved or copied.

| Symbol | Integer | `bool` | Floating Point | Overloading Trait |
|--------|-------------|-------------|----------------|--------------------|
| `-` | Negation* | | Negation | `std::ops::Neg` |
| `!` | Bitwise NOT | Logical NOT | | `std::ops::Not` |
| Symbol | Integer | `bool` | Floating Point | Overloading Trait |
|--------|-------------|-------------- |----------------|--------------------|
| `-` | Negation* | | Negation | `std::ops::Neg` |
| `!` | Bitwise NOT | [Logical NOT] | | `std::ops::Not` |

\* Only for signed integer types.

Expand Down Expand Up @@ -202,18 +202,18 @@ types. Remember that signed integers are always represented using two's
complement. The operands of all of these operators are evaluated in [value
expression context][value expression] so are moved or copied.

| Symbol | Integer | `bool` | Floating Point | Overloading Trait | Overloading Compound Assignment Trait |
|--------|-------------------------|-------------|----------------|--------------------| ------------------------------------- |
| `+` | Addition | | Addition | `std::ops::Add` | `std::ops::AddAssign` |
| `-` | Subtraction | | Subtraction | `std::ops::Sub` | `std::ops::SubAssign` |
| `*` | Multiplication | | Multiplication | `std::ops::Mul` | `std::ops::MulAssign` |
| `/` | Division* | | Division | `std::ops::Div` | `std::ops::DivAssign` |
| `%` | Remainder | | Remainder | `std::ops::Rem` | `std::ops::RemAssign` |
| `&` | Bitwise AND | Logical AND | | `std::ops::BitAnd` | `std::ops::BitAndAssign` |
| <code>&#124;</code> | Bitwise OR | Logical OR | | `std::ops::BitOr` | `std::ops::BitOrAssign` |
| `^` | Bitwise XOR | Logical XOR | | `std::ops::BitXor` | `std::ops::BitXorAssign` |
| `<<` | Left Shift | | | `std::ops::Shl` | `std::ops::ShlAssign` |
| `>>` | Right Shift** | | | `std::ops::Shr` | `std::ops::ShrAssign` |
| Symbol | Integer | `bool` | Floating Point | Overloading Trait | Overloading Compound Assignment Trait |
|--------|-------------------------|---------------|----------------|--------------------| ------------------------------------- |
| `+` | Addition | | Addition | `std::ops::Add` | `std::ops::AddAssign` |
| `-` | Subtraction | | Subtraction | `std::ops::Sub` | `std::ops::SubAssign` |
| `*` | Multiplication | | Multiplication | `std::ops::Mul` | `std::ops::MulAssign` |
| `/` | Division* | | Division | `std::ops::Div` | `std::ops::DivAssign` |
| `%` | Remainder | | Remainder | `std::ops::Rem` | `std::ops::RemAssign` |
| `&` | Bitwise AND | [Logical AND] | | `std::ops::BitAnd` | `std::ops::BitAndAssign` |
| <code>&#124;</code> | Bitwise OR | [Logical OR] | | `std::ops::BitOr` | `std::ops::BitOrAssign` |
| `^` | Bitwise XOR | [Logical XOR] | | `std::ops::BitXor` | `std::ops::BitXorAssign` |
| `<<` | Left Shift | | | `std::ops::Shl` | `std::ops::ShlAssign` |
| `>>` | Right Shift** | | | `std::ops::Shr` | `std::ops::ShrAssign` |

\* Integer division rounds towards zero.

Expand Down Expand Up @@ -522,6 +522,10 @@ dependency.

[copies or moves]: ../expressions.md#moved-and-copied-types
[dropping]: ../destructors.md
[logical and]: ../types/boolean.md#logical-and
[logical not]: ../types/boolean.md#logical-not
[logical or]: ../types/boolean.md#logical-or
[logical xor]: ../types/boolean.md#logical-xor
[mutable]: ../expressions.md#mutability
[place expression]: ../expressions.md#place-expressions-and-value-expressions
[unit]: ../types/tuple.md
Expand Down
16 changes: 10 additions & 6 deletions src/items/unions.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@ let f = unsafe { u.f1 };
Unions have no notion of an "active field". Instead, every union access just
interprets the storage at the type of the field used for the access. Reading a
union field reads the bits of the union at the field's type. Fields might have a
non-zero offset (except when `#[repr(C)]` is used); in that case the bits
starting at the offset of the fields are read. It is the programmer's
non-zero offset (except when [the C representation] is used); in that case the
bits starting at the offset of the fields are read. It is the programmer's
responsibility to make sure that the data is valid at the field's type. Failing
to do so results in undefined behavior. For example, reading the value `3` at
type `bool` is undefined behavior. Effectively, writing to and then reading from
a `#[repr(C)]` union is analogous to a [`transmute`] from the type used for
writing to the type used for reading.
to do so results in [undefined behavior]. For example, reading the value `3`
through of a field of the [boolean type] is undefined behavior. Effectively,
writing to and then reading from a union with [the C representation] is
analogous to a [`transmute`] from the type used for writing to the type used for
reading.

Consequently, all reads of union fields have to be placed in `unsafe` blocks:

Expand Down Expand Up @@ -182,4 +183,7 @@ checking, etc etc etc).
[_StructFields_]: structs.md
[`transmute`]: ../../std/mem/fn.transmute.html
[`Copy`]: ../../std/marker/trait.Copy.html
[boolean type]: ../types/boolean.md
[ManuallyDrop]: ../../std/mem/struct.ManuallyDrop.html
[the C representation]: ../type-layout.md#reprc-unions
[undefined behavior]: ../behavior-considered-undefined.html
127 changes: 114 additions & 13 deletions src/types/boolean.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,118 @@
# Boolean type

The `bool` type is a datatype which can be either `true` or `false`. The boolean
type uses one byte of memory. It is used in comparisons and bitwise operations
like `&`, `|`, and `!`.

```rust
fn main() {
let x = true;
let y: bool = false; // with the boolean type annotation

// Use of booleans in conditional expressions
if x {
println!("x is true");
}
}
let b: bool = true;
```

The *boolean type* or *bool* is a primitive data type that can take on one of
two values, called *true* and *false*.

Values of this type may be created using a [literal expression] using the
keywords `true` and `false` corresponding to the value of the same name.

This type is a part of the [language prelude] with the [name] `bool`.

An object with the boolean type has a [size and alignment] of 1 each. The
value false has the bit pattern `0x00` and the value true has the bit pattern
`0x01`. It is [undefined behavior] for an object with the boolean type to have
any other bit pattern.

The boolean type is the type of many operands in various [expressions]:

* The condition operand in [if expressions] and [while expressions]
* The operands in [lazy boolean operator expressions][lazy]

> **Note**: The boolean type acts similarly to but is not an [enumerated type].
In practice, this mostly means that constructors are not associated to the type
(e.g. `bool::true`).

Like all primitives, the boolean type [implements][p-impl] the
[traits][p-traits] [`Clone`][p-clone], [`Copy`][p-copy], [`Sized`][p-sized],
[`Send`][p-send], and [`Sync`][p-sync].

> **Note**: See the [standard library docs][std] for library operations.
## Operations on boolean values

<!-- This is washy wording --> When using certain operator expressions with a
boolean type for its operands, they evaluate using the rules of [boolean logic].

### Logical not

| `b` | [`!b`][op-not] |
|- | - |
| `true` | `false` |
| `false` | `true` |

### Logical or

| `a` | `b` | [<code>a &#124; b</code>][op-or] |
|- | - | - |
| `true` | `true` | `true` |
| `true` | `false` | `true` |
| `false` | `true` | `true` |
| `false` | `false` | `false` |

### Logical and

| `a` | `b` | [`a & b`][op-and] |
|- | - | - |
| `true` | `true` | `true` |
| `true` | `false` | `false` |
| `false` | `true` | `false` |
| `false` | `false` | `false` |

### Logical xor

| `a` | `b` | [`a ^ b`][op-xor] |
|- | - | - |
| `true` | `true` | `false` |
| `true` | `false` | `true` |
| `false` | `true` | `true` |
| `false` | `false` | `false` |

### Comparisons

| `a` | `b` | [`a == b`][op-compare] |
|- | - | - |
| `true` | `true` | `true` |
| `true` | `false` | `false` |
| `false` | `true` | `false` |
| `false` | `false` | `true` |

| `a` | `b` | [`a > b`][op-compare] |
|- | - | - |
| `true` | `true` | `false` |
| `true` | `false` | `true` |
| `false` | `true` | `false` |
| `false` | `false` | `false` |

* `a != b` is the same as `!(a == b)`
* `a >= b` is the same as `a == b | a > b`
* `a < b` is the same as `!(a >= b)`
* `a <= b` is the same as `a == b | a < b`

[boolean logic]: https://en.wikipedia.org/wiki/Boolean_algebra
[enumerated type]: enum.md
[expressions]: ../expressions.md
[if expressions]: ../expressions/if-expr.md#if-expressions
[language prelude]: ../names/preludes.md#language-prelude
[lazy]: ../expressions/operator-expr.md#lazy-boolean-operators
[literal expression]: ../expressions/literal-expr.md
[name]: ../names.md
[op-and]: ../expressions/operator-expr.md#arithmetic-and-logical-binary-operators
[op-compare]: ../expressions/operator-expr.md#comparison-operators
[op-not]: ../expressions/operator-expr.md#negation-operators
[op-or]: ../expressions/operator-expr.md#arithmetic-and-logical-binary-operators
[op-xor]: ../expressions/operator-expr.md#arithmetic-and-logical-binary-operators
[p-clone]: ../special-types-and-traits.md#clone
[p-copy]: ../special-types-and-traits.md#copy
[p-impl]: ../items/implementations.md
[p-send]: ../special-types-and-traits.md#send
[p-sized]: ../special-types-and-traits.md#sized
[p-sync]: ../special-types-and-traits.md#sync
[p-traits]: ../items/traits.md
[size and alignment]: ../type-layout.md#size-and-alignment
[std]: ../../std/primitive.bool.html
[undefined behavior]: ../behavior-considered-undefined.md
[while expressions]: ../expressions/loop-expr.md#predicate-loops

0 comments on commit 5037683

Please sign in to comment.