summaryrefslogtreecommitdiffstats
path: root/src/doc/reference
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc/reference')
-rw-r--r--src/doc/reference/.github/workflows/main.yml4
-rw-r--r--src/doc/reference/src/attributes/codegen.md24
-rw-r--r--src/doc/reference/src/behavior-considered-undefined.md25
-rw-r--r--src/doc/reference/src/destructors.md2
-rw-r--r--src/doc/reference/src/expressions.md2
-rw-r--r--src/doc/reference/src/expressions/operator-expr.md6
-rw-r--r--src/doc/reference/src/items/external-blocks.md2
-rw-r--r--src/doc/reference/src/trait-bounds.md73
-rw-r--r--src/doc/reference/src/type-layout.md30
-rw-r--r--src/doc/reference/src/types/never.md23
-rw-r--r--src/doc/reference/src/types/textual.md2
-rw-r--r--src/doc/reference/src/unsafe-keyword.md4
12 files changed, 156 insertions, 41 deletions
diff --git a/src/doc/reference/.github/workflows/main.yml b/src/doc/reference/.github/workflows/main.yml
index 4456c3c9c..aff208478 100644
--- a/src/doc/reference/.github/workflows/main.yml
+++ b/src/doc/reference/.github/workflows/main.yml
@@ -1,5 +1,7 @@
name: CI
-on: [push, pull_request]
+on:
+ pull_request:
+ merge_group:
jobs:
test:
diff --git a/src/doc/reference/src/attributes/codegen.md b/src/doc/reference/src/attributes/codegen.md
index 8629e835d..c929f979c 100644
--- a/src/doc/reference/src/attributes/codegen.md
+++ b/src/doc/reference/src/attributes/codegen.md
@@ -361,15 +361,20 @@ trait object whose methods are attributed.
## The `instruction_set` attribute
-The *`instruction_set` attribute* may be applied to a function to enable code generation for a specific
-instruction set supported by the target architecture. It uses the [_MetaListPath_] syntax and a path
-comprised of the architecture and instruction set to specify how to generate the code for
-architectures where a single program may utilize multiple instruction sets.
+The *`instruction_set` [attribute]* may be applied to a function to control which instruction set the function will be generated for.
+This allows mixing more than one instruction set in a single program on CPU architectures that support it.
+It uses the [_MetaListPath_] syntax, and a path comprised of the architecture family name and instruction set name.
-The following values are available on targets for the `ARMv4` and `ARMv5te` architectures:
+[_MetaListPath_]: ../attributes.md#meta-item-attribute-syntax
+
+It is a compilation error to use the `instruction_set` attribute on a target that does not support it.
+
+### On ARM
-* `arm::a32` - Uses ARM code.
-* `arm::t32` - Uses Thumb code.
+For the `ARMv4T` and `ARMv5te` architectures, the following are supported:
+
+* `arm::a32` - Generate the function as A32 "ARM" code.
+* `arm::t32` - Generate the function as T32 "Thumb" code.
<!-- ignore: arm-only -->
```rust,ignore
@@ -380,4 +385,7 @@ fn foo_arm_code() {}
fn bar_thumb_code() {}
```
-[_MetaListPath_]: ../attributes.md#meta-item-attribute-syntax
+Using the `instruction_set` attribute has the following effects:
+
+* If the address of the function is taken as a function pointer, the low bit of the address will be set to 0 (arm) or 1 (thumb) depending on the instruction set.
+* Any inline assembly in the function must use the specified instruction set instead of the target default.
diff --git a/src/doc/reference/src/behavior-considered-undefined.md b/src/doc/reference/src/behavior-considered-undefined.md
index 31963d1e5..9d1732d07 100644
--- a/src/doc/reference/src/behavior-considered-undefined.md
+++ b/src/doc/reference/src/behavior-considered-undefined.md
@@ -42,9 +42,12 @@ code.
All this also applies when values of these
types are passed in a (nested) field of a compound type, but not behind
pointer indirections.
-* Mutating immutable data. All data inside a [`const`] item is immutable. Moreover, all
- data reached through a shared reference or data owned by an immutable binding
- is immutable, unless that data is contained within an [`UnsafeCell<U>`].
+* Mutating immutable bytes. All bytes inside a [`const`] item are immutable.
+ The bytes owned by an immutable binding are immutable, unless those bytes are part of an [`UnsafeCell<U>`].
+
+ Moreover, the bytes [pointed to] by a shared reference, including transitively through other references (both shared and mutable) and `Box`es, are immutable; transitivity includes those references stored in fields of compound types.
+
+ A mutation is any write of more than 0 bytes which overlaps with any of the relevant bytes (even if that write does not change the memory contents).
* Invoking undefined behavior via compiler intrinsics.
* Executing code compiled with platform features that the current platform
does not support (see [`target_feature`]), *except* if the platform explicitly documents this to be safe.
@@ -74,6 +77,11 @@ code.
> `rustc_layout_scalar_valid_range_*` attributes.
* Incorrect use of inline assembly. For more details, refer to the [rules] to
follow when writing code that uses inline assembly.
+* **In [const context](const_eval.md#const-context)**: transmuting or otherwise
+ reinterpreting a pointer (reference, raw pointer, or function pointer) into
+ some allocated object as a non-pointer type (such as integers).
+ 'Reinterpreting' refers to loading the pointer value at integer type without a
+ cast, e.g. by doing raw pointer casts or using a union.
**Note:** Uninitialized memory is also implicitly invalid for any type that has
a restricted set of valid values. In other words, the only cases in which
@@ -86,13 +94,16 @@ reading uninitialized memory is permitted are inside `union`s and in "padding"
> vice versa, undefined behavior in Rust can cause adverse affects on code
> executed by any FFI calls to other languages.
+### Pointed-to bytes
+
+The span of bytes a pointer or reference "points to" is determined by the pointer value and the size of the pointee type (using `size_of_val`).
+
### Dangling pointers
[dangling]: #dangling-pointers
A reference/pointer is "dangling" if it is null or not all of the bytes it
-points to are part of the same live allocation (so in particular they all have to be
-part of *some* allocation). The span of bytes it points to is determined by the
-pointer value and the size of the pointee type (using `size_of_val`).
+[points to] are part of the same live allocation (so in particular they all have to be
+part of *some* allocation).
If the size is 0, then the pointer must either point inside of a live allocation
(including pointing just after the last byte of the allocation), or it must be
@@ -116,3 +127,5 @@ must never exceed `isize::MAX`.
[dereference expression]: expressions/operator-expr.md#the-dereference-operator
[place expression context]: expressions.md#place-expressions-and-value-expressions
[rules]: inline-assembly.md#rules-for-inline-assembly
+[points to]: #pointed-to-bytes
+[pointed to]: #pointed-to-bytes
diff --git a/src/doc/reference/src/destructors.md b/src/doc/reference/src/destructors.md
index 84aac89d3..17afc3676 100644
--- a/src/doc/reference/src/destructors.md
+++ b/src/doc/reference/src/destructors.md
@@ -284,7 +284,7 @@ An *extending pattern* is either
* An [identifier pattern] that binds by reference or mutable reference.
* A [struct][struct pattern], [tuple][tuple pattern], [tuple struct][tuple
struct pattern], or [slice][slice pattern] pattern where at least one of the
- direct subpatterns is a extending pattern.
+ direct subpatterns is an extending pattern.
So `ref x`, `V(ref x)` and `[ref x, y]` are all extending patterns, but `x`,
`&ref x` and `&(ref x,)` are not.
diff --git a/src/doc/reference/src/expressions.md b/src/doc/reference/src/expressions.md
index b2411cd8e..ad4cc5f54 100644
--- a/src/doc/reference/src/expressions.md
+++ b/src/doc/reference/src/expressions.md
@@ -162,7 +162,7 @@ Explicitly, the assignee expressions are:
- Place expressions.
- [Underscores][_UnderscoreExpression_].
- [Tuples][_TupleExpression_] of assignee expressions.
-- [Slices][_ArrayExpression_] of assingee expressions.
+- [Slices][_ArrayExpression_] of assignee expressions.
- [Tuple structs][_StructExpression_] of assignee expressions.
- [Structs][_StructExpression_] of assignee expressions (with optionally named
fields).
diff --git a/src/doc/reference/src/expressions/operator-expr.md b/src/doc/reference/src/expressions/operator-expr.md
index 691f801e8..8b6429636 100644
--- a/src/doc/reference/src/expressions/operator-expr.md
+++ b/src/doc/reference/src/expressions/operator-expr.md
@@ -243,8 +243,8 @@ The operands of all of these operators are evaluated in [value expression contex
| `+` | 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` |
+| `/` | 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` |
@@ -258,6 +258,8 @@ The operands of all of these operators are evaluated in [value expression contex
\*\*\* Arithmetic right shift on signed integer types, logical right shift on
unsigned integer types.
+† For integer types, division by zero panics.
+
Here are examples of these operators being used.
```rust
diff --git a/src/doc/reference/src/items/external-blocks.md b/src/doc/reference/src/items/external-blocks.md
index 25ae37bc3..982f57ba7 100644
--- a/src/doc/reference/src/items/external-blocks.md
+++ b/src/doc/reference/src/items/external-blocks.md
@@ -90,6 +90,8 @@ There are also some platform-specific ABI strings:
`__fastcall` and GCC and clang's `__attribute__((fastcall))`
* `extern "vectorcall"` -- The `vectorcall` ABI -- corresponds to MSVC's
`__vectorcall` and clang's `__attribute__((vectorcall))`
+* `extern "thiscall"` -- The default for C++ member functions on MSVC -- corresponds to MSVC's
+ `__thiscall` and GCC and clang's `__attribute__((thiscall))`
* `extern "efiapi"` -- The ABI used for [UEFI] functions.
## Variadic functions
diff --git a/src/doc/reference/src/trait-bounds.md b/src/doc/reference/src/trait-bounds.md
index 0a6731288..a7cd5a7d9 100644
--- a/src/doc/reference/src/trait-bounds.md
+++ b/src/doc/reference/src/trait-bounds.md
@@ -156,6 +156,79 @@ fn call_on_ref_zero<F>(f: F) where F: for<'a> Fn(&'a i32) {
}
```
+## Implied bounds
+
+Lifetime bounds required for types to be well-formed are sometimes inferred.
+
+```rust
+fn requires_t_outlives_a<'a, T>(x: &'a T) {}
+```
+The type parameter `T` is required to outlive `'a` for the type `&'a T` to be well-formed.
+This is inferred because the function signature contains the type `&'a T` which is
+only valid if `T: 'a` holds.
+
+Implied bounds are added for all parameters and outputs of functions. Inside of `requires_t_outlives_a`
+you can assume `T: 'a` to hold even if you don't explicitly specify this:
+
+```rust
+fn requires_t_outlives_a_not_implied<'a, T: 'a>() {}
+
+fn requires_t_outlives_a<'a, T>(x: &'a T) {
+ // This compiles, because `T: 'a` is implied by
+ // the reference type `&'a T`.
+ requires_t_outlives_a_not_implied::<'a, T>();
+}
+```
+
+```rust,compile_fail,E0309
+# fn requires_t_outlives_a_not_implied<'a, T: 'a>() {}
+fn not_implied<'a, T>() {
+ // This errors, because `T: 'a` is not implied by
+ // the function signature.
+ requires_t_outlives_a_not_implied::<'a, T>();
+}
+```
+
+Only lifetime bounds are implied, trait bounds still have to be explicitly added.
+The following example therefore causes an error:
+
+```rust,compile_fail,E0277
+use std::fmt::Debug;
+struct IsDebug<T: Debug>(T);
+// error[E0277]: `T` doesn't implement `Debug`
+fn doesnt_specify_t_debug<T>(x: IsDebug<T>) {}
+```
+
+Lifetime bounds are also inferred for type definitions and impl blocks for any type:
+
+```rust
+struct Struct<'a, T> {
+ // This requires `T: 'a` to be well-formed
+ // which is inferred by the compiler.
+ field: &'a T,
+}
+
+enum Enum<'a, T> {
+ // This requires `T: 'a` to be well-formed,
+ // which is inferred by the compiler.
+ //
+ // Note that `T: 'a` is required even when only
+ // using `Enum::OtherVariant`.
+ SomeVariant(&'a T),
+ OtherVariant,
+}
+
+trait Trait<'a, T: 'a> {}
+
+// This would error because `T: 'a` is not implied by any type
+// in the impl header.
+// impl<'a, T> Trait<'a, T> for () {}
+
+// This compiles as `T: 'a` is implied by the self type `&'a T`.
+impl<'a, T> Trait<'a, T> for &'a T {}
+```
+
+
[LIFETIME_OR_LABEL]: tokens.md#lifetimes-and-loop-labels
[_GenericParams_]: items/generics.md
[_TypePath_]: paths.md#paths-in-types
diff --git a/src/doc/reference/src/type-layout.md b/src/doc/reference/src/type-layout.md
index 191567a42..4c87954f3 100644
--- a/src/doc/reference/src/type-layout.md
+++ b/src/doc/reference/src/type-layout.md
@@ -549,13 +549,28 @@ The `align` modifier can also be applied on an `enum`.
When it is, the effect on the `enum`'s alignment is the same as if the `enum`
was wrapped in a newtype `struct` with the same `align` modifier.
-<div class="warning">
-
-***Warning:*** Dereferencing an unaligned pointer is [undefined behavior] and
-it is possible to [safely create unaligned pointers to `packed` fields][27060].
-Like all ways to create undefined behavior in safe Rust, this is a bug.
-
-</div>
+> Note: References to unaligned fields are not allowed because it is [undefined behavior].
+> When fields are unaligned due to an alignment modifier, consider the following options for using references and dereferences:
+>
+> ```rust
+> #[repr(packed)]
+> struct Packed {
+> f1: u8,
+> f2: u16,
+> }
+> let mut e = Packed { f1: 1, f2: 2 };
+> // Instead of creating a reference to a field, copy the value to a local variable.
+> let x = e.f2;
+> // Or in situations like `println!` which creates a reference, use braces
+> // to change it to a copy of the value.
+> println!("{}", {e.f2});
+> // Or if you need a pointer, use the unaligned methods for reading and writing
+> // instead of dereferencing the pointer directly.
+> let ptr: *const u16 = std::ptr::addr_of!(e.f2);
+> let value = unsafe { ptr.read_unaligned() };
+> let mut_ptr: *mut u16 = std::ptr::addr_of_mut!(e.f2);
+> unsafe { mut_ptr.write_unaligned(3) }
+> ```
### The `transparent` Representation
@@ -587,7 +602,6 @@ used with any other representation.
[enumerations]: items/enumerations.md
[zero-variant enums]: items/enumerations.md#zero-variant-enums
[undefined behavior]: behavior-considered-undefined.md
-[27060]: https://github.com/rust-lang/rust/issues/27060
[55149]: https://github.com/rust-lang/rust/issues/55149
[`PhantomData<T>`]: special-types-and-traits.md#phantomdatat
[Default]: #the-default-representation
diff --git a/src/doc/reference/src/types/never.md b/src/doc/reference/src/types/never.md
index e32674272..3fbd2ad5c 100644
--- a/src/doc/reference/src/types/never.md
+++ b/src/doc/reference/src/types/never.md
@@ -7,16 +7,17 @@ The never type `!` is a type with no values, representing the result of
computations that never complete. Expressions of type `!` can be coerced into
any other type.
-<!-- ignore: unstable -->
-```rust,ignore
-let x: ! = panic!();
-// Can be coerced into any type.
-let y: u32 = x;
+The `!` type can **only** appear in function return types presently,
+indicating it is a diverging function that never returns.
+
+```rust
+fn foo() -> ! {
+ panic!("This call never returns.");
+}
```
-**NB.** The never type was expected to be stabilized in 1.41, but due
-to some last minute regressions detected the stabilization was
-temporarily reverted. The `!` type can only appear in function return
-types presently. See [the tracking
-issue](https://github.com/rust-lang/rust/issues/35121) for more
-details.
+```rust
+extern "C" {
+ pub fn no_return_extern_func() -> !;
+}
+```
diff --git a/src/doc/reference/src/types/textual.md b/src/doc/reference/src/types/textual.md
index 7f3899d70..65d563312 100644
--- a/src/doc/reference/src/types/textual.md
+++ b/src/doc/reference/src/types/textual.md
@@ -8,7 +8,7 @@ or 0xE000 to 0x10FFFF range. It is immediate [Undefined Behavior] to create a
`char` that falls outside this range. A `[char]` is effectively a UCS-4 / UTF-32
string of length 1.
-A value of type `str` is represented the same way as `[u8]`, it is a slice of
+A value of type `str` is represented the same way as `[u8]`, a slice of
8-bit unsigned bytes. However, the Rust standard library makes extra assumptions
about `str`: methods working on `str` assume and ensure that the data in there
is valid UTF-8. Calling a `str` method with a non-UTF-8 buffer can cause
diff --git a/src/doc/reference/src/unsafe-keyword.md b/src/doc/reference/src/unsafe-keyword.md
index 5fa5deea6..a29fc9432 100644
--- a/src/doc/reference/src/unsafe-keyword.md
+++ b/src/doc/reference/src/unsafe-keyword.md
@@ -27,9 +27,9 @@ this can be changed by enabling the [`unsafe_op_in_unsafe_fn`] lint.
By putting operations into an unsafe block, the programmer states that they have taken care of satisfying the extra safety conditions of all operations inside that block.
Unsafe blocks are the logical dual to unsafe functions:
-where unsafe functions define a proof obligation that callers must uphold, unsafe blocks state that all relevant proof obligations have been discharged.
+where unsafe functions define a proof obligation that callers must uphold, unsafe blocks state that all relevant proof obligations of functions or operations called inside the block have been discharged.
There are many ways to discharge proof obligations;
-for example, there could be run-time checks or data structure invariants that guarantee that certain properties are definitely true, or the unsafe block could be inside an `unsafe fn` and use its own proof obligations to discharge the proof obligations of its callees.
+for example, there could be run-time checks or data structure invariants that guarantee that certain properties are definitely true, or the unsafe block could be inside an `unsafe fn`, in which case the block can use the proof obligations of that function to discharge the proof obligations arising inside the block.
Unsafe blocks are used to wrap foreign libraries, make direct use of hardware or implement features not directly present in the language.
For example, Rust provides the language features necessary to implement memory-safe concurrency in the language but the implementation of threads and message passing in the standard library uses unsafe blocks.