) {}
+```
+
+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/type-layout.md b/src/type-layout.md
index 191567a42..4c87954f3 100644
--- a/src/type-layout.md
+++ b/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.
-
-
-***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.
-
-
+> 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`]: special-types-and-traits.md#phantomdatat
[Default]: #the-default-representation
diff --git a/src/types/impl-trait.md b/src/types/impl-trait.md
index 413f999f8..af900408e 100644
--- a/src/types/impl-trait.md
+++ b/src/types/impl-trait.md
@@ -31,15 +31,15 @@ The caller must provide a type that satisfies the bounds declared by the anonymo
For example, these two forms are almost equivalent:
-```rust,ignore
+```rust
trait Trait {}
// generic type parameter
-fn foo(arg: T) {
+fn with_generic_type(arg: T) {
}
// impl Trait in argument position
-fn foo(arg: impl Trait) {
+fn with_impl_trait(arg: impl Trait) {
}
```
@@ -96,16 +96,24 @@ With `impl Trait`, unlike with a generic type parameter, the function chooses th
The function:
-```rust,ignore
+```rust
+# trait Trait {}
fn foo() -> T {
+ // ...
+# panic!()
+}
```
allows the caller to determine the return type, `T`, and the function returns that type.
The function:
-```rust,ignore
+```rust
+# trait Trait {}
+# impl Trait for () {}
fn foo() -> impl Trait {
+ // ...
+}
```
doesn't allow the caller to determine the return type.
diff --git a/src/types/never.md b/src/types/never.md
index e32674272..3fbd2ad5c 100644
--- a/src/types/never.md
+++ b/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.
-
-```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/types/textual.md b/src/types/textual.md
index 7f3899d70..65d563312 100644
--- a/src/types/textual.md
+++ b/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/unsafe-keyword.md b/src/unsafe-keyword.md
index 5fa5deea6..a29fc9432 100644
--- a/src/unsafe-keyword.md
+++ b/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.