diff --git a/RELEASES.md b/RELEASES.md
index 024610bc7a417..1f940e6bc2d3b 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,151 @@
+Version 1.52.0 (2021-05-06)
+============================
+
+Language
+--------
+- [Added the `unsafe_op_in_unsafe_fn` lint, which checks whether the unsafe code
+  in an `unsafe fn` is wrapped in a `unsafe` block.][79208] This lint
+  is allowed by default, and may become a warning or hard error in a
+  future edition.
+- [You can now cast mutable references to arrays to a pointer of the same type as
+  the element.][81479]
+
+Compiler
+--------
+- [Upgraded the default LLVM to LLVM 12.][81451]
+
+Added tier 3\* support for the following targets.
+
+- [`s390x-unknown-linux-musl`][82166]
+- [`riscv32gc-unknown-linux-musl` & `riscv64gc-unknown-linux-musl`][82202]
+- [`powerpc-unknown-openbsd`][82733]
+
+\* Refer to Rust's [platform support page][platform-support-doc] for more
+information on Rust's tiered platform support.
+
+Libraries
+---------
+- [`OsString` now implements `Extend` and `FromIterator`.][82121]
+- [`cmp::Reverse` now has `#[repr(transparent)]` representation.][81879]
+- [`Arc<impl Error>` now implements `error::Error`.][80553]
+- [All integer division and remainder operations are now `const`.][80962]
+
+Stabilised APIs
+-------------
+- [`Arguments::as_str`]
+- [`char::MAX`]
+- [`char::REPLACEMENT_CHARACTER`]
+- [`char::UNICODE_VERSION`]
+- [`char::decode_utf16`]
+- [`char::from_digit`]
+- [`char::from_u32_unchecked`]
+- [`char::from_u32`]
+- [`slice::partition_point`]
+- [`str::rsplit_once`]
+- [`str::split_once`]
+
+The following previously stable APIs are now `const`.
+
+- [`char::len_utf8`]
+- [`char::len_utf16`]
+- [`char::to_ascii_uppercase`]
+- [`char::to_ascii_lowercase`]
+- [`char::eq_ignore_ascii_case`]
+- [`u8::to_ascii_uppercase`]
+- [`u8::to_ascii_lowercase`]
+- [`u8::eq_ignore_ascii_case`]
+
+Rustdoc
+-------
+- [Rustdoc lints are now treated as a tool lint, meaning that
+  lints are now prefixed with `rustdoc::` (e.g. `#[warn(rustdoc::non_autolinks)]`).][80527]
+  Using the old style is still allowed, and will become a warning in
+  a future release.
+- [Rustdoc now supports argument files.][82261]
+- [Rustdoc now generates smart punctuation for documentation.][79423]
+- [You can now use "task lists" in Rustdoc Markdown.][81766] E.g.
+  ```markdown
+  - [x] Complete
+  - [ ] Todo
+  ```
+
+Misc
+----
+- [You can now pass multiple filters to tests.][81356] E.g.
+  `cargo test -- foo bar` will run all tests that match `foo` and `bar`.
+- [Rustup now distributes PDB symbols for the `std` library on Windows,
+  allowing you to see `std` symbols when debugging.][82218]
+
+Internal Only
+-------------
+These changes provide no direct user facing benefits, but represent significant
+improvements to the internals and overall performance of rustc and
+related tools.
+
+- [Check the result cache before the DepGraph when ensuring queries][81855]
+- [Try fast_reject::simplify_type in coherence before doing full check][81744]
+- [Only store a LocalDefId in some HIR nodes][81611]
+- [Store HIR attributes in a side table][79519]
+
+Compatibility Notes
+-------------------
+- [Cargo build scripts are now forbidden from setting `RUSTC_BOOTSTRAP`.][cargo/9181]
+- [Removed support for the `x86_64-rumprun-netbsd` target.][82594]
+- [Deprecated the `x86_64-sun-solaris` target in favor of `x86_64-pc-solaris`.][82216]
+- [Rustdoc now only accepts `,`, ` `, and `\t` as delimiters for specifying
+  languages in code blocks.][78429]
+- [Rustc now catches more cases of `pub_use_of_private_extern_crate`][80763]
+- [Changes in how proc macros handle whitespace may lead to panics when used
+  with older `proc-macro-hack` versions. A `cargo update` should be sufficient to fix this in all cases.][84136]
+
+[84136]: https://github.com/rust-lang/rust/issues/84136
+[80763]: https://github.com/rust-lang/rust/pull/80763
+[82166]: https://github.com/rust-lang/rust/pull/82166
+[82121]: https://github.com/rust-lang/rust/pull/82121
+[81879]: https://github.com/rust-lang/rust/pull/81879
+[82261]: https://github.com/rust-lang/rust/pull/82261
+[82218]: https://github.com/rust-lang/rust/pull/82218
+[82216]: https://github.com/rust-lang/rust/pull/82216
+[82202]: https://github.com/rust-lang/rust/pull/82202
+[81855]: https://github.com/rust-lang/rust/pull/81855
+[81766]: https://github.com/rust-lang/rust/pull/81766
+[81744]: https://github.com/rust-lang/rust/pull/81744
+[81611]: https://github.com/rust-lang/rust/pull/81611
+[81479]: https://github.com/rust-lang/rust/pull/81479
+[81451]: https://github.com/rust-lang/rust/pull/81451
+[81356]: https://github.com/rust-lang/rust/pull/81356
+[80962]: https://github.com/rust-lang/rust/pull/80962
+[80553]: https://github.com/rust-lang/rust/pull/80553
+[80527]: https://github.com/rust-lang/rust/pull/80527
+[79519]: https://github.com/rust-lang/rust/pull/79519
+[79423]: https://github.com/rust-lang/rust/pull/79423
+[79208]: https://github.com/rust-lang/rust/pull/79208
+[78429]: https://github.com/rust-lang/rust/pull/78429
+[82733]: https://github.com/rust-lang/rust/pull/82733
+[82594]: https://github.com/rust-lang/rust/pull/82594
+[cargo/9181]: https://github.com/rust-lang/cargo/pull/9181
+[`char::MAX`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.MAX
+[`char::REPLACEMENT_CHARACTER`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.REPLACEMENT_CHARACTER
+[`char::UNICODE_VERSION`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.UNICODE_VERSION
+[`char::decode_utf16`]: https://doc.rust-lang.org/std/primitive.char.html#method.decode_utf16
+[`char::from_u32`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_u32
+[`char::from_u32_unchecked`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_u32_unchecked
+[`char::from_digit`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_digit
+[`Peekable::next_if`]: https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if
+[`Peekable::next_if_eq`]: https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if_eq
+[`Arguments::as_str`]: https://doc.rust-lang.org/stable/std/fmt/struct.Arguments.html#method.as_str
+[`str::split_once`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_once
+[`str::rsplit_once`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.rsplit_once
+[`slice::partition_point`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.partition_point
+[`char::len_utf8`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.len_utf8
+[`char::len_utf16`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.len_utf16
+[`char::to_ascii_uppercase`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_ascii_uppercase
+[`char::to_ascii_lowercase`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_ascii_lowercase
+[`char::eq_ignore_ascii_case`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.eq_ignore_ascii_case
+[`u8::to_ascii_uppercase`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ascii_uppercase
+[`u8::to_ascii_lowercase`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ascii_lowercase
+[`u8::eq_ignore_ascii_case`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.eq_ignore_ascii_case
+
 Version 1.51.0 (2021-03-25)
 ============================
 
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index d4970a4f5321f..e452463fbf5de 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -171,7 +171,6 @@ impl fmt::Display for InvalidProgramInfo<'_> {
 #[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
 pub enum CheckInAllocMsg {
     MemoryAccessTest,
-    NullPointerTest,
     PointerArithmeticTest,
     InboundsTest,
 }
@@ -185,7 +184,6 @@ impl fmt::Display for CheckInAllocMsg {
             "{}",
             match *self {
                 CheckInAllocMsg::MemoryAccessTest => "memory access",
-                CheckInAllocMsg::NullPointerTest => "null pointer test",
                 CheckInAllocMsg::PointerArithmeticTest => "pointer arithmetic",
                 CheckInAllocMsg::InboundsTest => "inbounds test",
             }
@@ -308,9 +306,6 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
                 ptr.alloc_id,
                 allocation_size.bytes()
             ),
-            DanglingIntPointer(_, CheckInAllocMsg::NullPointerTest) => {
-                write!(f, "null pointer is not allowed for this operation")
-            }
             DanglingIntPointer(i, msg) => {
                 write!(f, "{} failed: 0x{:x} is not a valid pointer", msg, i)
             }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 1ddd7d694547d..08d6f4a46fefe 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2332,17 +2332,17 @@ crate mod dep_tracking {
     }
 
     macro_rules! impl_dep_tracking_hash_via_hash {
-        ($t:ty) => {
+        ($($t:ty),+ $(,)?) => {$(
             impl DepTrackingHash for $t {
                 fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) {
                     Hash::hash(self, hasher);
                 }
             }
-        };
+        )+};
     }
 
     macro_rules! impl_dep_tracking_hash_for_sortable_vec_of {
-        ($t:ty) => {
+        ($($t:ty),+ $(,)?) => {$(
             impl DepTrackingHash for Vec<$t> {
                 fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) {
                     let mut elems: Vec<&$t> = self.iter().collect();
@@ -2354,61 +2354,65 @@ crate mod dep_tracking {
                     }
                 }
             }
-        };
-    }
+        )+};
+    }
+
+    impl_dep_tracking_hash_via_hash!(
+        bool,
+        usize,
+        u64,
+        String,
+        PathBuf,
+        lint::Level,
+        Option<bool>,
+        Option<u32>,
+        Option<usize>,
+        Option<NonZeroUsize>,
+        Option<String>,
+        Option<(String, u64)>,
+        Option<Vec<String>>,
+        Option<MergeFunctions>,
+        Option<RelocModel>,
+        Option<CodeModel>,
+        Option<TlsModel>,
+        Option<WasiExecModel>,
+        Option<PanicStrategy>,
+        Option<RelroLevel>,
+        Option<InstrumentCoverage>,
+        Option<lint::Level>,
+        Option<PathBuf>,
+        CrateType,
+        MergeFunctions,
+        PanicStrategy,
+        RelroLevel,
+        Passes,
+        OptLevel,
+        LtoCli,
+        DebugInfo,
+        UnstableFeatures,
+        OutputTypes,
+        NativeLibKind,
+        SanitizerSet,
+        CFGuard,
+        TargetTriple,
+        Edition,
+        LinkerPluginLto,
+        Option<SplitDebuginfo>,
+        SwitchWithOptPath,
+        Option<SymbolManglingVersion>,
+        Option<SourceFileHashAlgorithm>,
+        TrimmedDefPaths,
+    );
 
-    impl_dep_tracking_hash_via_hash!(bool);
-    impl_dep_tracking_hash_via_hash!(usize);
-    impl_dep_tracking_hash_via_hash!(u64);
-    impl_dep_tracking_hash_via_hash!(String);
-    impl_dep_tracking_hash_via_hash!(PathBuf);
-    impl_dep_tracking_hash_via_hash!(lint::Level);
-    impl_dep_tracking_hash_via_hash!(Option<bool>);
-    impl_dep_tracking_hash_via_hash!(Option<u32>);
-    impl_dep_tracking_hash_via_hash!(Option<usize>);
-    impl_dep_tracking_hash_via_hash!(Option<NonZeroUsize>);
-    impl_dep_tracking_hash_via_hash!(Option<String>);
-    impl_dep_tracking_hash_via_hash!(Option<(String, u64)>);
-    impl_dep_tracking_hash_via_hash!(Option<Vec<String>>);
-    impl_dep_tracking_hash_via_hash!(Option<MergeFunctions>);
-    impl_dep_tracking_hash_via_hash!(Option<RelocModel>);
-    impl_dep_tracking_hash_via_hash!(Option<CodeModel>);
-    impl_dep_tracking_hash_via_hash!(Option<TlsModel>);
-    impl_dep_tracking_hash_via_hash!(Option<WasiExecModel>);
-    impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
-    impl_dep_tracking_hash_via_hash!(Option<RelroLevel>);
-    impl_dep_tracking_hash_via_hash!(Option<InstrumentCoverage>);
-    impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
-    impl_dep_tracking_hash_via_hash!(Option<PathBuf>);
-    impl_dep_tracking_hash_via_hash!(CrateType);
-    impl_dep_tracking_hash_via_hash!(MergeFunctions);
-    impl_dep_tracking_hash_via_hash!(PanicStrategy);
-    impl_dep_tracking_hash_via_hash!(RelroLevel);
-    impl_dep_tracking_hash_via_hash!(Passes);
-    impl_dep_tracking_hash_via_hash!(OptLevel);
-    impl_dep_tracking_hash_via_hash!(LtoCli);
-    impl_dep_tracking_hash_via_hash!(DebugInfo);
-    impl_dep_tracking_hash_via_hash!(UnstableFeatures);
-    impl_dep_tracking_hash_via_hash!(OutputTypes);
-    impl_dep_tracking_hash_via_hash!(NativeLibKind);
-    impl_dep_tracking_hash_via_hash!(SanitizerSet);
-    impl_dep_tracking_hash_via_hash!(CFGuard);
-    impl_dep_tracking_hash_via_hash!(TargetTriple);
-    impl_dep_tracking_hash_via_hash!(Edition);
-    impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
-    impl_dep_tracking_hash_via_hash!(Option<SplitDebuginfo>);
-    impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
-    impl_dep_tracking_hash_via_hash!(Option<SymbolManglingVersion>);
-    impl_dep_tracking_hash_via_hash!(Option<SourceFileHashAlgorithm>);
-    impl_dep_tracking_hash_via_hash!(TrimmedDefPaths);
-
-    impl_dep_tracking_hash_for_sortable_vec_of!(String);
-    impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
-    impl_dep_tracking_hash_for_sortable_vec_of!((PathBuf, PathBuf));
-    impl_dep_tracking_hash_for_sortable_vec_of!(CrateType);
-    impl_dep_tracking_hash_for_sortable_vec_of!((String, lint::Level));
-    impl_dep_tracking_hash_for_sortable_vec_of!((String, Option<String>, NativeLibKind));
-    impl_dep_tracking_hash_for_sortable_vec_of!((String, u64));
+    impl_dep_tracking_hash_for_sortable_vec_of!(
+        String,
+        PathBuf,
+        (PathBuf, PathBuf),
+        CrateType,
+        (String, lint::Level),
+        (String, Option<String>, NativeLibKind),
+        (String, u64)
+    );
 
     impl<T1, T2> DepTrackingHash for (T1, T2)
     where
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 73e35f0171aa7..b2e4e7a981d20 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -579,6 +579,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
 
                 let mut restrict_type_params = false;
+                let mut unsatisfied_bounds = false;
                 if !unsatisfied_predicates.is_empty() {
                     let def_span = |def_id| {
                         self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
@@ -739,6 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         err.note(&format!(
                             "the following trait bounds were not satisfied:\n{bound_list}"
                         ));
+                        unsatisfied_bounds = true;
                     }
                 }
 
@@ -752,6 +754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         source,
                         out_of_scope_traits,
                         &unsatisfied_predicates,
+                        unsatisfied_bounds,
                     );
                 }
 
@@ -984,9 +987,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         source: SelfSource<'tcx>,
         valid_out_of_scope_traits: Vec<DefId>,
         unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)],
+        unsatisfied_bounds: bool,
     ) {
         let mut alt_rcvr_sugg = false;
-        if let SelfSource::MethodCall(rcvr) = source {
+        if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
             debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
             let skippable = [
                 self.tcx.lang_items().clone_trait(),
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 51d5f4ebe2bd2..97b6f5cf41211 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -191,7 +191,25 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
                     Res::Def(DefKind::Ctor(..), def_id) => {
                         tcx.generics_of(tcx.parent(def_id).unwrap())
                     }
-                    Res::Def(_, def_id) => tcx.generics_of(def_id),
+                    // Other `DefKind`s don't have generics and would ICE when calling
+                    // `generics_of`.
+                    Res::Def(
+                        DefKind::Struct
+                        | DefKind::Union
+                        | DefKind::Enum
+                        | DefKind::Variant
+                        | DefKind::Trait
+                        | DefKind::OpaqueTy
+                        | DefKind::TyAlias
+                        | DefKind::ForeignTy
+                        | DefKind::TraitAlias
+                        | DefKind::AssocTy
+                        | DefKind::Fn
+                        | DefKind::AssocFn
+                        | DefKind::AssocConst
+                        | DefKind::Impl,
+                        def_id,
+                    ) => tcx.generics_of(def_id),
                     Res::Err => {
                         tcx.sess.delay_span_bug(tcx.def_span(def_id), "anon const with Res::Err");
                         return None;
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 415bdde11eb88..2c324b15a1a1a 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -720,9 +720,6 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 ///
 /// ## On `packed` structs
 ///
-/// It is currently impossible to create raw pointers to unaligned fields
-/// of a packed struct.
-///
 /// Attempting to create a raw pointer to an `unaligned` struct field with
 /// an expression such as `&packed.unaligned as *const FieldType` creates an
 /// intermediate unaligned reference before converting that to a raw pointer.
@@ -731,9 +728,13 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 /// As a result, using `&packed.unaligned as *const FieldType` causes immediate
 /// *undefined behavior* in your program.
 ///
+/// Instead you must use the [`ptr::addr_of!`](addr_of) macro to
+/// create the pointer. You may use that returned pointer together with this
+/// function.
+///
 /// An example of what not to do and how this relates to `read_unaligned` is:
 ///
-/// ```no_run
+/// ```
 /// #[repr(packed, C)]
 /// struct Packed {
 ///     _padding: u8,
@@ -745,24 +746,15 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 ///     unaligned: 0x01020304,
 /// };
 ///
-/// #[allow(unaligned_references)]
-/// let v = unsafe {
-///     // Here we attempt to take the address of a 32-bit integer which is not aligned.
-///     let unaligned =
-///         // A temporary unaligned reference is created here which results in
-///         // undefined behavior regardless of whether the reference is used or not.
-///         &packed.unaligned
-///         // Casting to a raw pointer doesn't help; the mistake already happened.
-///         as *const u32;
+/// // Take the address of a 32-bit integer which is not aligned.
+/// // In contrast to `&packed.unaligned as *const _`, this has no undefined behavior.
+/// let unaligned = std::ptr::addr_of!(packed.unaligned);
 ///
-///     let v = std::ptr::read_unaligned(unaligned);
-///
-///     v
-/// };
+/// let v = unsafe { std::ptr::read_unaligned(unaligned) };
+/// assert_eq!(v, 0x01020304);
 /// ```
 ///
 /// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
-// FIXME: Update docs based on outcome of RFC #2582 and friends.
 ///
 /// # Examples
 ///
@@ -916,9 +908,6 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
 ///
 /// ## On `packed` structs
 ///
-/// It is currently impossible to create raw pointers to unaligned fields
-/// of a packed struct.
-///
 /// Attempting to create a raw pointer to an `unaligned` struct field with
 /// an expression such as `&packed.unaligned as *const FieldType` creates an
 /// intermediate unaligned reference before converting that to a raw pointer.
@@ -927,36 +916,32 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
 /// As a result, using `&packed.unaligned as *const FieldType` causes immediate
 /// *undefined behavior* in your program.
 ///
-/// An example of what not to do and how this relates to `write_unaligned` is:
+/// Instead you must use the [`ptr::addr_of_mut!`](addr_of_mut)
+/// macro to create the pointer. You may use that returned pointer together with
+/// this function.
+///
+/// An example of how to do it and how this relates to `write_unaligned` is:
 ///
-/// ```no_run
+/// ```
 /// #[repr(packed, C)]
 /// struct Packed {
 ///     _padding: u8,
 ///     unaligned: u32,
 /// }
 ///
-/// let v = 0x01020304;
 /// let mut packed: Packed = unsafe { std::mem::zeroed() };
 ///
-/// #[allow(unaligned_references)]
-/// let v = unsafe {
-///     // Here we attempt to take the address of a 32-bit integer which is not aligned.
-///     let unaligned =
-///         // A temporary unaligned reference is created here which results in
-///         // undefined behavior regardless of whether the reference is used or not.
-///         &mut packed.unaligned
-///         // Casting to a raw pointer doesn't help; the mistake already happened.
-///         as *mut u32;
+/// // Take the address of a 32-bit integer which is not aligned.
+/// // In contrast to `&packed.unaligned as *mut _`, this has no undefined behavior.
+/// let unaligned = std::ptr::addr_of_mut!(packed.unaligned);
 ///
-///     std::ptr::write_unaligned(unaligned, v);
+/// unsafe { std::ptr::write_unaligned(unaligned, 42) };
 ///
-///     v
-/// };
+/// assert_eq!({packed.unaligned}, 42); // `{...}` forces copying the field instead of creating a reference.
 /// ```
 ///
-/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
-// FIXME: Update docs based on outcome of RFC #2582 and friends.
+/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however
+/// (as can be seen in the `assert_eq!` above).
 ///
 /// # Examples
 ///
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index ec28cdd1ba0d9..0923175414edd 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -1948,8 +1948,9 @@ impl<T> [T] {
     /// assert!(!v.contains(&50));
     /// ```
     ///
-    /// If you do not have an `&T`, but just an `&U` such that `T: Borrow<U>`
-    /// (e.g. `String: Borrow<str>`), you can use `iter().any`:
+    /// If you do not have a `&T`, but some other value that you can compare
+    /// with one (for example, `String` implements `PartialEq<str>`), you can
+    /// use `iter().any`:
     ///
     /// ```
     /// let v = [String::from("hello"), String::from("world")]; // slice of `String`
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index bfea39e3211fc..489b722440362 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -518,13 +518,11 @@ impl Duration {
         if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
             let nanos = if self.nanos >= rhs.nanos {
                 self.nanos - rhs.nanos
+            } else if let Some(sub_secs) = secs.checked_sub(1) {
+                secs = sub_secs;
+                self.nanos + NANOS_PER_SEC - rhs.nanos
             } else {
-                if let Some(sub_secs) = secs.checked_sub(1) {
-                    secs = sub_secs;
-                    self.nanos + NANOS_PER_SEC - rhs.nanos
-                } else {
-                    return None;
-                }
+                return None;
             };
             debug_assert!(nanos < NANOS_PER_SEC);
             Some(Duration { secs, nanos })
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 821e7d4cfe7ad..11d052dae9e90 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -61,6 +61,7 @@ pub fn current_dir() -> io::Result<PathBuf> {
 /// assert!(env::set_current_dir(&root).is_ok());
 /// println!("Successfully changed working directory to {}!", root.display());
 /// ```
+#[doc(alias = "chdir")]
 #[stable(feature = "env", since = "1.0.0")]
 pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
     os_imp::chdir(path.as_ref())
diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs
index cd6b0b2d7ee7a..96ab32104ea2c 100644
--- a/library/std/src/primitive_docs.rs
+++ b/library/std/src/primitive_docs.rs
@@ -445,7 +445,27 @@ mod prim_unit {}
 /// Note that here the call to [`drop`] is for clarity - it indicates
 /// that we are done with the given value and it should be destroyed.
 ///
-/// ## 3. Get it from C.
+/// ## 3. Create it using `ptr::addr_of!`
+///
+/// Instead of coercing a reference to a raw pointer, you can use the macros
+/// [`ptr::addr_of!`] (for `*const T`) and [`ptr::addr_of_mut!`] (for `*mut T`).
+/// These macros allow you to create raw pointers to fields to which you cannot
+/// create a reference (without causing undefined behaviour), such as an
+/// unaligned field. This might be necessary if packed structs or uninitialized
+/// memory is involved.
+///
+/// ```
+/// #[derive(Debug, Default, Copy, Clone)]
+/// #[repr(C, packed)]
+/// struct S {
+///     aligned: u8,
+///     unaligned: u32,
+/// }
+/// let s = S::default();
+/// let p = std::ptr::addr_of!(s.unaligned); // not allowed with coercion
+/// ```
+///
+/// ## 4. Get it from C.
 ///
 /// ```
 /// # #![feature(rustc_private)]
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index de9c1882c7d48..db443756de3d0 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1110,6 +1110,19 @@ struct Compiletest {
     compare_mode: Option<&'static str>,
 }
 
+impl Compiletest {
+    fn add_lld_flags(builder: &Builder<'_>, target: TargetSelection, flags: &mut Vec<String>) {
+        if builder.config.use_lld {
+            if builder.is_fuse_ld_lld(target) {
+                flags.push("-Clink-arg=-fuse-ld=lld".to_string());
+            }
+
+            let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" };
+            flags.push(format!("-Clink-arg=-Wl,{}", threads));
+        }
+    }
+}
+
 impl Step for Compiletest {
     type Output = ();
 
@@ -1250,18 +1263,12 @@ note: if you're sure you want to do this, please open an issue as to why. In the
 
         let mut hostflags = flags.clone();
         hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display()));
-        if builder.is_fuse_ld_lld(compiler.host) {
-            hostflags.push("-Clink-args=-fuse-ld=lld".to_string());
-            hostflags.push("-Clink-arg=-Wl,--threads=1".to_string());
-        }
+        Self::add_lld_flags(builder, compiler.host, &mut hostflags);
         cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
 
         let mut targetflags = flags;
         targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display()));
-        if builder.is_fuse_ld_lld(target) {
-            targetflags.push("-Clink-args=-fuse-ld=lld".to_string());
-            targetflags.push("-Clink-arg=-Wl,--threads=1".to_string());
-        }
+        Self::add_lld_flags(builder, target, &mut targetflags);
         cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
 
         cmd.arg("--docck-python").arg(builder.python());
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index b3c67b84da617..f9a7599c49744 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -113,7 +113,7 @@ The `std` column in the table below has the following meanings:
 [`no_std`]: https://rust-embedded.github.io/book/intro/no-std.html
 
 target | std | notes
--------|-----|-------
+-------|:---:|-------
 `aarch64-apple-ios` | ✓ | ARM64 iOS
 `aarch64-fuchsia` | ✓ | ARM64 Fuchsia
 `aarch64-linux-android` | ✓ | ARM64 Android
@@ -194,7 +194,7 @@ The `host` column indicates whether the codebase includes support for building
 host tools.
 
 target | std | host | notes
--------|-----|------|-------
+-------|:---:|:----:|-------
 `aarch64-apple-ios-macabi` | ? |  | Apple Catalyst on ARM64
 `aarch64-apple-ios-sim` | ? |  | Apple iOS Simulator on ARM64
 `aarch64-apple-tvos` | * |  | ARM64 tvOS
diff --git a/src/test/ui/suggestions/import-trait-for-method-call.rs b/src/test/ui/suggestions/import-trait-for-method-call.rs
index 646f68dea14e8..4dbadbdf98206 100644
--- a/src/test/ui/suggestions/import-trait-for-method-call.rs
+++ b/src/test/ui/suggestions/import-trait-for-method-call.rs
@@ -6,4 +6,11 @@ fn next_u64() -> u64 {
     h.finish() //~ ERROR no method named `finish` found for struct `DefaultHasher`
 }
 
-fn main() {}
+trait Bar {}
+impl Bar for String {}
+
+fn main() {
+    let s = String::from("hey");
+    let x: &dyn Bar = &s;
+    x.as_ref(); //~ ERROR the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds
+}
diff --git a/src/test/ui/suggestions/import-trait-for-method-call.stderr b/src/test/ui/suggestions/import-trait-for-method-call.stderr
index f3ae20552f3d5..a2b9b9d14ab09 100644
--- a/src/test/ui/suggestions/import-trait-for-method-call.stderr
+++ b/src/test/ui/suggestions/import-trait-for-method-call.stderr
@@ -15,6 +15,22 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f
 LL | use std::hash::Hasher;
    |
 
-error: aborting due to previous error
+error[E0599]: the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds were not satisfied
+  --> $DIR/import-trait-for-method-call.rs:15:7
+   |
+LL | trait Bar {}
+   | --------- doesn't satisfy `dyn Bar: AsRef<_>`
+...
+LL |     x.as_ref();
+   |       ^^^^^^ method cannot be called on `&dyn Bar` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `dyn Bar: AsRef<_>`
+           which is required by `&dyn Bar: AsRef<_>`
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following trait defines an item `as_ref`, perhaps you need to implement it:
+           candidate #1: `AsRef`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/typeck/issue-84831.rs b/src/test/ui/typeck/issue-84831.rs
new file mode 100644
index 0000000000000..c646f71072532
--- /dev/null
+++ b/src/test/ui/typeck/issue-84831.rs
@@ -0,0 +1,9 @@
+fn f() {
+    std::<0>; //~ ERROR expected value
+}
+fn j() {
+    std::<_ as _>; //~ ERROR expected value
+    //~^ ERROR expected one of `,` or `>`, found keyword `as`
+}
+
+fn main () {}
diff --git a/src/test/ui/typeck/issue-84831.stderr b/src/test/ui/typeck/issue-84831.stderr
new file mode 100644
index 0000000000000..e3cce10a00fd1
--- /dev/null
+++ b/src/test/ui/typeck/issue-84831.stderr
@@ -0,0 +1,26 @@
+error: expected one of `,` or `>`, found keyword `as`
+  --> $DIR/issue-84831.rs:5:13
+   |
+LL |     std::<_ as _>;
+   |             ^^ expected one of `,` or `>`
+   |
+help: expressions must be enclosed in braces to be used as const generic arguments
+   |
+LL |     std::<{ _ as _ }>;
+   |           ^        ^
+
+error[E0423]: expected value, found crate `std`
+  --> $DIR/issue-84831.rs:2:5
+   |
+LL |     std::<0>;
+   |     ^^^^^^^^ not a value
+
+error[E0423]: expected value, found crate `std`
+  --> $DIR/issue-84831.rs:5:5
+   |
+LL |     std::<_ as _>;
+   |     ^^^^^^^^^^^^^ not a value
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0423`.