diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index e7d243bfcb0f7..b22eb1ff6354b 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -245,7 +245,7 @@ where
     fn replace(&mut self, key: K) -> Option<K> {
         let root = Self::ensure_is_owned(&mut self.root);
         match search::search_tree::<marker::Mut<'_>, K, (), K>(root.node_as_mut(), &key) {
-            Found(handle) => Some(mem::replace(handle.into_kv_mut().0, key)),
+            Found(handle) => Some(mem::replace(handle.into_key_mut(), key)),
             GoDown(handle) => {
                 VacantEntry { key, handle, length: &mut self.length, _marker: PhantomData }
                     .insert(());
@@ -811,7 +811,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     {
         let root_node = self.root.as_mut()?.node_as_mut();
         match search::search_tree(root_node, key) {
-            Found(handle) => Some(handle.into_kv_mut().1),
+            Found(handle) => Some(handle.into_val_mut()),
             GoDown(_) => None,
         }
     }
@@ -2748,7 +2748,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_mut(self) -> &'a mut V {
-        self.handle.into_kv_mut().1
+        self.handle.into_val_mut()
     }
 
     /// Sets the value of the entry with the `OccupiedEntry`'s key,
@@ -3024,3 +3024,6 @@ impl<K: Ord, V, I: Iterator<Item = (K, V)>> Iterator for MergeIter<K, V, I> {
         }
     }
 }
+
+#[cfg(test)]
+mod tests;
diff --git a/library/alloc/tests/btree/map.rs b/library/alloc/src/collections/btree/map/tests.rs
similarity index 99%
rename from library/alloc/tests/btree/map.rs
rename to library/alloc/src/collections/btree/map/tests.rs
index 5777bd6090714..910e7043092a5 100644
--- a/library/alloc/tests/btree/map.rs
+++ b/library/alloc/src/collections/btree/map/tests.rs
@@ -1,16 +1,20 @@
-use std::collections::btree_map::Entry::{Occupied, Vacant};
-use std::collections::BTreeMap;
+use crate::boxed::Box;
+use crate::collections::btree_map::Entry::{Occupied, Vacant};
+use crate::collections::BTreeMap;
+use crate::fmt::Debug;
+use crate::rc::Rc;
+use crate::string::String;
+use crate::string::ToString;
+use crate::vec::Vec;
 use std::convert::TryFrom;
-use std::fmt::Debug;
 use std::iter::FromIterator;
 use std::mem;
 use std::ops::Bound::{self, Excluded, Included, Unbounded};
 use std::ops::RangeBounds;
 use std::panic::{catch_unwind, AssertUnwindSafe};
-use std::rc::Rc;
 use std::sync::atomic::{AtomicUsize, Ordering};
 
-use super::DeterministicRng;
+use super::super::DeterministicRng;
 
 // Value of node::CAPACITY, thus capacity of a tree with a single level,
 // i.e. a tree who's root is a leaf node at height 0.
diff --git a/library/alloc/src/collections/btree/mod.rs b/library/alloc/src/collections/btree/mod.rs
index 543ff41a4d48d..6c8a588eb58f3 100644
--- a/library/alloc/src/collections/btree/mod.rs
+++ b/library/alloc/src/collections/btree/mod.rs
@@ -25,3 +25,30 @@ pub unsafe fn unwrap_unchecked<T>(val: Option<T>) -> T {
         }
     })
 }
+
+#[cfg(test)]
+/// XorShiftRng
+struct DeterministicRng {
+    x: u32,
+    y: u32,
+    z: u32,
+    w: u32,
+}
+
+#[cfg(test)]
+impl DeterministicRng {
+    fn new() -> Self {
+        DeterministicRng { x: 0x193a6754, y: 0xa8a7d469, z: 0x97830e05, w: 0x113ba7bb }
+    }
+
+    fn next(&mut self) -> u32 {
+        let x = self.x;
+        let t = x ^ (x << 11);
+        self.x = self.y;
+        self.y = self.z;
+        self.z = self.w;
+        let w_ = self.w;
+        self.w = w_ ^ (w_ >> 19) ^ (t ^ (t >> 8));
+        self.w
+    }
+}
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index c0b75fd5eacec..acc2ae73572ba 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -43,6 +43,9 @@ use crate::boxed::Box;
 const B: usize = 6;
 pub const MIN_LEN: usize = B - 1;
 pub const CAPACITY: usize = 2 * B - 1;
+const KV_IDX_CENTER: usize = B - 1;
+const EDGE_IDX_LEFT_OF_CENTER: usize = B - 1;
+const EDGE_IDX_RIGHT_OF_CENTER: usize = B;
 
 /// The underlying representation of leaf nodes.
 #[repr(C)]
@@ -834,38 +837,12 @@ enum InsertionPlace {
 fn splitpoint(edge_idx: usize) -> (usize, InsertionPlace) {
     debug_assert!(edge_idx <= CAPACITY);
     // Rust issue #74834 tries to explain these symmetric rules.
-    let middle_kv_idx;
-    let insertion;
-    if edge_idx <= B - 2 {
-        middle_kv_idx = B - 2;
-        insertion = InsertionPlace::Left(edge_idx);
-    } else if edge_idx == B - 1 {
-        middle_kv_idx = B - 1;
-        insertion = InsertionPlace::Left(edge_idx);
-    } else if edge_idx == B {
-        middle_kv_idx = B - 1;
-        insertion = InsertionPlace::Right(0);
-    } else {
-        middle_kv_idx = B;
-        let new_edge_idx = edge_idx - (B + 1);
-        insertion = InsertionPlace::Right(new_edge_idx);
-    }
-    let mut left_len = middle_kv_idx;
-    let mut right_len = CAPACITY - middle_kv_idx - 1;
-    match insertion {
-        InsertionPlace::Left(edge_idx) => {
-            debug_assert!(edge_idx <= left_len);
-            left_len += 1;
-        }
-        InsertionPlace::Right(edge_idx) => {
-            debug_assert!(edge_idx <= right_len);
-            right_len += 1;
-        }
+    match edge_idx {
+        0..EDGE_IDX_LEFT_OF_CENTER => (KV_IDX_CENTER - 1, InsertionPlace::Left(edge_idx)),
+        EDGE_IDX_LEFT_OF_CENTER => (KV_IDX_CENTER, InsertionPlace::Left(edge_idx)),
+        EDGE_IDX_RIGHT_OF_CENTER => (KV_IDX_CENTER, InsertionPlace::Right(0)),
+        _ => (KV_IDX_CENTER + 1, InsertionPlace::Right(edge_idx - (KV_IDX_CENTER + 1 + 1))),
     }
-    debug_assert!(left_len >= MIN_LEN);
-    debug_assert!(right_len >= MIN_LEN);
-    debug_assert!(left_len + right_len == CAPACITY);
-    (middle_kv_idx, insertion)
 }
 
 impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::Edge> {
@@ -1067,6 +1044,16 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Immut<'a>, K, V, NodeTyp
 }
 
 impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
+    pub fn into_key_mut(self) -> &'a mut K {
+        let keys = self.node.into_key_slice_mut();
+        unsafe { keys.get_unchecked_mut(self.idx) }
+    }
+
+    pub fn into_val_mut(self) -> &'a mut V {
+        let vals = self.node.into_val_slice_mut();
+        unsafe { vals.get_unchecked_mut(self.idx) }
+    }
+
     pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) {
         unsafe {
             let (keys, vals) = self.node.into_slices_mut();
@@ -1261,8 +1248,8 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
         unsafe {
             let (k, v, edge) = self.reborrow_mut().left_edge().descend().pop();
 
-            let k = mem::replace(self.reborrow_mut().into_kv_mut().0, k);
-            let v = mem::replace(self.reborrow_mut().into_kv_mut().1, v);
+            let k = mem::replace(self.kv_mut().0, k);
+            let v = mem::replace(self.kv_mut().1, v);
 
             match self.reborrow_mut().right_edge().descend().force() {
                 ForceResult::Leaf(mut leaf) => leaf.push_front(k, v),
@@ -1278,8 +1265,8 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
         unsafe {
             let (k, v, edge) = self.reborrow_mut().right_edge().descend().pop_front();
 
-            let k = mem::replace(self.reborrow_mut().into_kv_mut().0, k);
-            let v = mem::replace(self.reborrow_mut().into_kv_mut().1, v);
+            let k = mem::replace(self.kv_mut().0, k);
+            let v = mem::replace(self.kv_mut().1, v);
 
             match self.reborrow_mut().left_edge().descend().force() {
                 ForceResult::Leaf(mut leaf) => leaf.push(k, v),
@@ -1307,7 +1294,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
                 let left_kv = left_node.reborrow_mut().into_kv_pointers_mut();
                 let right_kv = right_node.reborrow_mut().into_kv_pointers_mut();
                 let parent_kv = {
-                    let kv = self.reborrow_mut().into_kv_mut();
+                    let kv = self.kv_mut();
                     (kv.0 as *mut K, kv.1 as *mut V)
                 };
 
@@ -1364,7 +1351,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
                 let left_kv = left_node.reborrow_mut().into_kv_pointers_mut();
                 let right_kv = right_node.reborrow_mut().into_kv_pointers_mut();
                 let parent_kv = {
-                    let kv = self.reborrow_mut().into_kv_mut();
+                    let kv = self.kv_mut();
                     (kv.0 as *mut K, kv.1 as *mut V)
                 };
 
@@ -1590,3 +1577,6 @@ unsafe fn slice_remove<T>(slice: &mut [T], idx: usize) -> T {
         ret
     }
 }
+
+#[cfg(test)]
+mod tests;
diff --git a/library/alloc/src/collections/btree/node/tests.rs b/library/alloc/src/collections/btree/node/tests.rs
new file mode 100644
index 0000000000000..e2416974ddca3
--- /dev/null
+++ b/library/alloc/src/collections/btree/node/tests.rs
@@ -0,0 +1,25 @@
+use super::*;
+
+#[test]
+fn test_splitpoint() {
+    for idx in 0..=CAPACITY {
+        let (middle_kv_idx, insertion) = splitpoint(idx);
+
+        // Simulate performing the split:
+        let mut left_len = middle_kv_idx;
+        let mut right_len = CAPACITY - middle_kv_idx - 1;
+        match insertion {
+            InsertionPlace::Left(edge_idx) => {
+                assert!(edge_idx <= left_len);
+                left_len += 1;
+            }
+            InsertionPlace::Right(edge_idx) => {
+                assert!(edge_idx <= right_len);
+                right_len += 1;
+            }
+        }
+        assert!(left_len >= MIN_LEN);
+        assert!(right_len >= MIN_LEN);
+        assert!(left_len + right_len == CAPACITY);
+    }
+}
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 35f4ef1d9b4c7..a559e87e4e298 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1572,3 +1572,6 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
 
 #[stable(feature = "fused", since = "1.26.0")]
 impl<T: Ord> FusedIterator for Union<'_, T> {}
+
+#[cfg(test)]
+mod tests;
diff --git a/library/alloc/tests/btree/set.rs b/library/alloc/src/collections/btree/set/tests.rs
similarity index 98%
rename from library/alloc/tests/btree/set.rs
rename to library/alloc/src/collections/btree/set/tests.rs
index b6c34b7c6c346..f4e957e22fe15 100644
--- a/library/alloc/tests/btree/set.rs
+++ b/library/alloc/src/collections/btree/set/tests.rs
@@ -1,9 +1,10 @@
-use std::collections::BTreeSet;
+use crate::collections::BTreeSet;
+use crate::vec::Vec;
 use std::iter::FromIterator;
 use std::panic::{catch_unwind, AssertUnwindSafe};
 use std::sync::atomic::{AtomicU32, Ordering};
 
-use super::DeterministicRng;
+use super::super::DeterministicRng;
 
 #[test]
 fn test_clone_eq() {
@@ -15,24 +16,6 @@ fn test_clone_eq() {
     assert_eq!(m.clone(), m);
 }
 
-#[test]
-fn test_hash() {
-    use crate::hash;
-
-    let mut x = BTreeSet::new();
-    let mut y = BTreeSet::new();
-
-    x.insert(1);
-    x.insert(2);
-    x.insert(3);
-
-    y.insert(3);
-    y.insert(2);
-    y.insert(1);
-
-    assert_eq!(hash(&x), hash(&y));
-}
-
 #[test]
 fn test_iter_min_max() {
     let mut a = BTreeSet::new();
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 9ac23886d4e15..2d25941a52412 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -80,6 +80,7 @@
 #![feature(arbitrary_self_types)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(btree_drain_filter)]
 #![feature(cfg_sanitize)]
 #![feature(cfg_target_has_atomic)]
 #![feature(coerce_unsized)]
@@ -93,6 +94,7 @@
 #![feature(container_error_extra)]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
+#![feature(exclusive_range_pattern)]
 #![feature(extend_one)]
 #![feature(fmt_internals)]
 #![feature(fn_traits)]
@@ -101,6 +103,8 @@
 #![feature(lang_items)]
 #![feature(layout_for_ptr)]
 #![feature(libc)]
+#![feature(map_first_last)]
+#![feature(map_into_keys_values)]
 #![feature(negative_impls)]
 #![feature(new_uninit)]
 #![feature(nll)]
diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs
index de707a71a8c9e..8ca0a0883cb16 100644
--- a/library/alloc/src/vec.rs
+++ b/library/alloc/src/vec.rs
@@ -2620,9 +2620,6 @@ where
 ///
 /// This `struct` is created by the `into_iter` method on [`Vec`] (provided
 /// by the [`IntoIterator`] trait).
-///
-/// [`Vec`]: struct.Vec.html
-/// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<T> {
     buf: NonNull<T>,
@@ -2802,10 +2799,7 @@ unsafe impl<#[may_dangle] T> Drop for IntoIter<T> {
 
 /// A draining iterator for `Vec<T>`.
 ///
-/// This `struct` is created by the [`drain`] method on [`Vec`].
-///
-/// [`drain`]: struct.Vec.html#method.drain
-/// [`Vec`]: struct.Vec.html
+/// This `struct` is created by [`Vec::drain`].
 #[stable(feature = "drain", since = "1.6.0")]
 pub struct Drain<'a, T: 'a> {
     /// Index of tail to preserve
@@ -2933,11 +2927,8 @@ impl<T> FusedIterator for Drain<'_, T> {}
 
 /// A splicing iterator for `Vec`.
 ///
-/// This struct is created by the [`splice()`] method on [`Vec`]. See its
-/// documentation for more.
-///
-/// [`splice()`]: struct.Vec.html#method.splice
-/// [`Vec`]: struct.Vec.html
+/// This struct is created by [`Vec::splice()`].
+/// See its documentation for more.
 #[derive(Debug)]
 #[stable(feature = "vec_splice", since = "1.21.0")]
 pub struct Splice<'a, I: Iterator + 'a> {
diff --git a/library/alloc/tests/btree/mod.rs b/library/alloc/tests/btree/mod.rs
deleted file mode 100644
index 1d08ae13e0540..0000000000000
--- a/library/alloc/tests/btree/mod.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-mod map;
-mod set;
-
-/// XorShiftRng
-struct DeterministicRng {
-    x: u32,
-    y: u32,
-    z: u32,
-    w: u32,
-}
-
-impl DeterministicRng {
-    fn new() -> Self {
-        DeterministicRng { x: 0x193a6754, y: 0xa8a7d469, z: 0x97830e05, w: 0x113ba7bb }
-    }
-
-    fn next(&mut self) -> u32 {
-        let x = self.x;
-        let t = x ^ (x << 11);
-        self.x = self.y;
-        self.y = self.z;
-        self.z = self.w;
-        let w_ = self.w;
-        self.w = w_ ^ (w_ >> 19) ^ (t ^ (t >> 8));
-        self.w
-    }
-}
diff --git a/library/alloc/tests/btree_set_hash.rs b/library/alloc/tests/btree_set_hash.rs
new file mode 100644
index 0000000000000..e06a95ded94c7
--- /dev/null
+++ b/library/alloc/tests/btree_set_hash.rs
@@ -0,0 +1,19 @@
+use std::collections::BTreeSet;
+
+#[test]
+fn test_hash() {
+    use crate::hash;
+
+    let mut x = BTreeSet::new();
+    let mut y = BTreeSet::new();
+
+    x.insert(1);
+    x.insert(2);
+    x.insert(3);
+
+    y.insert(3);
+    y.insert(2);
+    y.insert(1);
+
+    assert_eq!(hash(&x), hash(&y));
+}
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 3aacd4a687e38..f2ba1ab64810b 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -1,10 +1,7 @@
 #![feature(allocator_api)]
 #![feature(box_syntax)]
-#![feature(btree_drain_filter)]
 #![feature(drain_filter)]
 #![feature(exact_size_is_empty)]
-#![feature(map_first_last)]
-#![feature(map_into_keys_values)]
 #![feature(new_uninit)]
 #![feature(pattern)]
 #![feature(str_split_once)]
@@ -25,7 +22,7 @@ mod arc;
 mod binary_heap;
 mod borrow;
 mod boxed;
-mod btree;
+mod btree_set_hash;
 mod cow_str;
 mod fmt;
 mod heap;
diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs
index 920f5e9c0bd28..e45aa86c0795a 100644
--- a/library/core/src/mem/manually_drop.rs
+++ b/library/core/src/mem/manually_drop.rs
@@ -56,9 +56,9 @@ use crate::ptr;
 /// working with [pinned] data, where reusing the memory without calling the destructor could lead
 /// to Undefined Behaviour.
 ///
-/// [`mem::zeroed`]: fn.zeroed.html
-/// [`MaybeUninit<T>`]: union.MaybeUninit.html
-/// [pinned]: ../pin/index.html
+/// [`mem::zeroed`]: crate::mem::zeroed
+/// [`MaybeUninit<T>`]: crate::mem::MaybeUninit
+/// [pinned]: crate::pin
 #[stable(feature = "manually_drop", since = "1.20.0")]
 #[lang = "manually_drop"]
 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -116,8 +116,6 @@ impl<T> ManuallyDrop<T> {
     /// leaving the state of this container unchanged.
     /// It is your responsibility to ensure that this `ManuallyDrop` is not used again.
     ///
-    /// [`ManuallyDrop::drop`]: #method.drop
-    /// [`ManuallyDrop::into_inner`]: #method.into_inner
     #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
     #[stable(feature = "manually_drop_take", since = "1.42.0")]
     #[inline]
@@ -148,9 +146,7 @@ impl<T: ?Sized> ManuallyDrop<T> {
     /// This is normally prevented by the type system, but users of `ManuallyDrop` must
     /// uphold those guarantees without assistance from the compiler.
     ///
-    /// [`ManuallyDrop::into_inner`]: #method.into_inner
-    /// [`ptr::drop_in_place`]: ../ptr/fn.drop_in_place.html
-    /// [pinned]: ../pin/index.html
+    /// [pinned]: crate::pin
     #[stable(feature = "manually_drop", since = "1.20.0")]
     #[inline]
     pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 027498d3911c8..d2d65fd2fa517 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -247,7 +247,7 @@ impl<T> MaybeUninit<T> {
     /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
     /// It is your responsibility to make sure `T` gets dropped if it got initialized.
     ///
-    /// [`assume_init`]: #method.assume_init
+    /// [`assume_init`]: MaybeUninit::assume_init
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
     #[rustc_const_stable(feature = "const_maybe_uninit", since = "1.36.0")]
     #[inline(always)]
@@ -525,7 +525,7 @@ impl<T> MaybeUninit<T> {
     /// to ensure that that data may indeed be duplicated.
     ///
     /// [inv]: #initialization-invariant
-    /// [`assume_init`]: #method.assume_init
+    /// [`assume_init`]: MaybeUninit::assume_init
     ///
     /// # Examples
     ///
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index fc07fa77b85e7..ef0ef415b4cba 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -16,7 +16,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core" }
-libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of-std'] }
+libc = { version = "0.2.74", default-features = false, features = ['rustc-dep-of-std'] }
 compiler_builtins = { version = "0.1.32" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index da25a0ede729d..11b3f22503e83 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -1,3 +1,4 @@
+#![deny(unsafe_op_in_unsafe_fn)]
 use crate::ascii;
 use crate::borrow::{Borrow, Cow};
 use crate::cmp::Ordering;
@@ -35,23 +36,23 @@ use crate::sys;
 /// example, you can build a `CString` straight out of a [`String`] or
 /// a [`&str`], since both implement that trait).
 ///
-/// The [`new`] method will actually check that the provided `&[u8]`
+/// The [`CString::new`] method will actually check that the provided `&[u8]`
 /// does not have 0 bytes in the middle, and return an error if it
 /// finds one.
 ///
 /// # Extracting a raw pointer to the whole C string
 ///
-/// `CString` implements a [`as_ptr`] method through the [`Deref`]
+/// `CString` implements a [`as_ptr`][`CStr::as_ptr`] method through the [`Deref`]
 /// trait. This method will give you a `*const c_char` which you can
 /// feed directly to extern functions that expect a nul-terminated
-/// string, like C's `strdup()`. Notice that [`as_ptr`] returns a
+/// string, like C's `strdup()`. Notice that [`as_ptr`][`CStr::as_ptr`] returns a
 /// read-only pointer; if the C code writes to it, that causes
 /// undefined behavior.
 ///
 /// # Extracting a slice of the whole C string
 ///
 /// Alternatively, you can obtain a `&[`[`u8`]`]` slice from a
-/// `CString` with the [`as_bytes`] method. Slices produced in this
+/// `CString` with the [`CString::as_bytes`] method. Slices produced in this
 /// way do *not* contain the trailing nul terminator. This is useful
 /// when you will be calling an extern function that takes a `*const
 /// u8` argument which is not necessarily nul-terminated, plus another
@@ -60,7 +61,7 @@ use crate::sys;
 /// [`len`][slice.len] method.
 ///
 /// If you need a `&[`[`u8`]`]` slice *with* the nul terminator, you
-/// can use [`as_bytes_with_nul`] instead.
+/// can use [`CString::as_bytes_with_nul`] instead.
 ///
 /// Once you have the kind of slice you need (with or without a nul
 /// terminator), you can call the slice's own
@@ -68,20 +69,11 @@ use crate::sys;
 /// extern functions. See the documentation for that function for a
 /// discussion on ensuring the lifetime of the raw pointer.
 ///
-/// [`Into`]: ../convert/trait.Into.html
-/// [`Vec`]: ../vec/struct.Vec.html
-/// [`String`]: ../string/struct.String.html
-/// [`&str`]: ../primitive.str.html
-/// [`u8`]: ../primitive.u8.html
-/// [`new`]: #method.new
-/// [`as_bytes`]: #method.as_bytes
-/// [`as_bytes_with_nul`]: #method.as_bytes_with_nul
-/// [`as_ptr`]: #method.as_ptr
+/// [`&str`]: str
 /// [slice.as_ptr]: ../primitive.slice.html#method.as_ptr
 /// [slice.len]: ../primitive.slice.html#method.len
-/// [`Deref`]: ../ops/trait.Deref.html
-/// [`CStr`]: struct.CStr.html
-/// [`&CStr`]: struct.CStr.html
+/// [`Deref`]: ops::Deref
+/// [`&CStr`]: CStr
 ///
 /// # Examples
 ///
@@ -113,7 +105,6 @@ use crate::sys;
 /// documentation of `CString` before use, as improper ownership management
 /// of `CString` instances can lead to invalid memory accesses, memory leaks,
 /// and other memory errors.
-
 #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct CString {
@@ -137,8 +128,8 @@ pub struct CString {
 ///
 /// Note that this structure is **not** `repr(C)` and is not recommended to be
 /// placed in the signatures of FFI functions. Instead, safe wrappers of FFI
-/// functions may leverage the unsafe [`from_ptr`] constructor to provide a safe
-/// interface to other consumers.
+/// functions may leverage the unsafe [`CStr::from_ptr`] constructor to provide
+/// a safe interface to other consumers.
 ///
 /// # Examples
 ///
@@ -189,11 +180,7 @@ pub struct CString {
 /// println!("string: {}", my_string_safe());
 /// ```
 ///
-/// [`u8`]: ../primitive.u8.html
-/// [`&str`]: ../primitive.str.html
-/// [`String`]: ../string/struct.String.html
-/// [`CString`]: struct.CString.html
-/// [`from_ptr`]: #method.from_ptr
+/// [`&str`]: str
 #[derive(Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
 // FIXME:
@@ -218,9 +205,6 @@ pub struct CStr {
 /// This error is created by the [`new`][`CString::new`] method on
 /// [`CString`]. See its documentation for more.
 ///
-/// [`CString`]: struct.CString.html
-/// [`CString::new`]: struct.CString.html#method.new
-///
 /// # Examples
 ///
 /// ```
@@ -237,12 +221,9 @@ pub struct NulError(usize, Vec<u8>);
 /// The slice used to create a [`CStr`] must have one and only one nul byte,
 /// positioned at the end.
 ///
-/// This error is created by the [`from_bytes_with_nul`] method on [`CStr`].
+/// This error is created by the [`CStr::from_bytes_with_nul`] method.
 /// See its documentation for more.
 ///
-/// [`CStr`]: struct.CStr.html
-/// [`from_bytes_with_nul`]: struct.CStr.html#method.from_bytes_with_nul
-///
 /// # Examples
 ///
 /// ```
@@ -261,12 +242,9 @@ pub struct FromBytesWithNulError {
 /// The vector used to create a [`CString`] must have one and only one nul byte,
 /// positioned at the end.
 ///
-/// This error is created by the [`from_vec_with_nul`] method on [`CString`].
+/// This error is created by the [`CString::from_vec_with_nul`] method.
 /// See its documentation for more.
 ///
-/// [`CString`]: struct.CString.html
-/// [`from_vec_with_nul`]: struct.CString.html#method.from_vec_with_nul
-///
 /// # Examples
 ///
 /// ```
@@ -316,8 +294,6 @@ impl FromVecWithNulError {
     ///
     /// assert_eq!(&bytes[..], value.unwrap_err().as_bytes());
     /// ```
-    ///
-    /// [`CString`]: struct.CString.html
     pub fn as_bytes(&self) -> &[u8] {
         &self.bytes[..]
     }
@@ -343,8 +319,6 @@ impl FromVecWithNulError {
     ///
     /// assert_eq!(bytes, value.unwrap_err().into_bytes());
     /// ```
-    ///
-    /// [`CString`]: struct.CString.html
     pub fn into_bytes(self) -> Vec<u8> {
         self.bytes
     }
@@ -352,17 +326,12 @@ impl FromVecWithNulError {
 
 /// An error indicating invalid UTF-8 when converting a [`CString`] into a [`String`].
 ///
-/// `CString` is just a wrapper over a buffer of bytes with a nul
-/// terminator; [`into_string`][`CString::into_string`] performs UTF-8
-/// validation on those bytes and may return this error.
+/// `CString` is just a wrapper over a buffer of bytes with a nul terminator;
+/// [`CString::into_string`] performs UTF-8 validation on those bytes and may
+/// return this error.
 ///
-/// This `struct` is created by the
-/// [`into_string`][`CString::into_string`] method on [`CString`]. See
+/// This `struct` is created by [`CString::into_string()`]. See
 /// its documentation for more.
-///
-/// [`String`]: ../string/struct.String.html
-/// [`CString`]: struct.CString.html
-/// [`CString::into_string`]: struct.CString.html#method.into_string
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "cstring_into", since = "1.7.0")]
 pub struct IntoStringError {
@@ -398,8 +367,6 @@ impl CString {
     /// This function will return an error if the supplied bytes contain an
     /// internal 0 byte. The [`NulError`] returned will contain the bytes as well as
     /// the position of the nul byte.
-    ///
-    /// [`NulError`]: struct.NulError.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
         trait SpecIntoVec {
@@ -439,11 +406,9 @@ impl CString {
     /// Creates a C-compatible string by consuming a byte vector,
     /// without checking for interior 0 bytes.
     ///
-    /// This method is equivalent to [`new`] except that no runtime assertion
-    /// is made that `v` contains no 0 bytes, and it requires an actual
-    /// byte vector, not anything that can be converted to one with Into.
-    ///
-    /// [`new`]: #method.new
+    /// This method is equivalent to [`CString::new`] except that no runtime
+    /// assertion is made that `v` contains no 0 bytes, and it requires an
+    /// actual byte vector, not anything that can be converted to one with Into.
     ///
     /// # Examples
     ///
@@ -462,21 +427,22 @@ impl CString {
         CString { inner: v.into_boxed_slice() }
     }
 
-    /// Retakes ownership of a `CString` that was transferred to C via [`into_raw`].
+    /// Retakes ownership of a `CString` that was transferred to C via
+    /// [`CString::into_raw`].
     ///
     /// Additionally, the length of the string will be recalculated from the pointer.
     ///
     /// # Safety
     ///
     /// This should only ever be called with a pointer that was earlier
-    /// obtained by calling [`into_raw`] on a `CString`. Other usage (e.g., trying to take
+    /// obtained by calling [`CString::into_raw`]. Other usage (e.g., trying to take
     /// ownership of a string that was allocated by foreign code) is likely to lead
     /// to undefined behavior or allocator corruption.
     ///
     /// It should be noted that the length isn't just "recomputed," but that
     /// the recomputed length must match the original length from the
-    /// [`into_raw`] call. This means the [`into_raw`]/`from_raw` methods
-    /// should not be used when passing the string to C functions that can
+    /// [`CString::into_raw`] call. This means the [`CString::into_raw`]/`from_raw`
+    /// methods should not be used when passing the string to C functions that can
     /// modify the string's length.
     ///
     /// > **Note:** If you need to borrow a string that was allocated by
@@ -485,9 +451,6 @@ impl CString {
     /// > make your own provisions for freeing it appropriately, likely
     /// > with the foreign code's API to do that.
     ///
-    /// [`into_raw`]: #method.into_raw
-    /// [`CStr`]: struct.CStr.html
-    ///
     /// # Examples
     ///
     /// Creates a `CString`, pass ownership to an `extern` function (via raw pointer), then retake
@@ -510,26 +473,31 @@ impl CString {
     /// ```
     #[stable(feature = "cstr_memory", since = "1.4.0")]
     pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
-        let len = sys::strlen(ptr) + 1; // Including the NUL byte
-        let slice = slice::from_raw_parts_mut(ptr, len as usize);
-        CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) }
+        // SAFETY: This is called with a pointer that was obtained from a call
+        // to `CString::into_raw` and the length has not been modified. As such,
+        // we know there is a NUL byte (and only one) at the end and that the
+        // information about the size of the allocation is correct on Rust's
+        // side.
+        unsafe {
+            let len = sys::strlen(ptr) + 1; // Including the NUL byte
+            let slice = slice::from_raw_parts_mut(ptr, len as usize);
+            CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) }
+        }
     }
 
     /// Consumes the `CString` and transfers ownership of the string to a C caller.
     ///
     /// The pointer which this function returns must be returned to Rust and reconstituted using
-    /// [`from_raw`] to be properly deallocated. Specifically, one
+    /// [`CString::from_raw`] to be properly deallocated. Specifically, one
     /// should *not* use the standard C `free()` function to deallocate
     /// this string.
     ///
-    /// Failure to call [`from_raw`] will lead to a memory leak.
+    /// Failure to call [`CString::from_raw`] will lead to a memory leak.
     ///
     /// The C side must **not** modify the length of the string (by writing a
     /// `NULL` somewhere inside the string or removing the final one) before
-    /// it makes it back into Rust using [`from_raw`]. See the safety section
-    /// in [`from_raw`].
-    ///
-    /// [`from_raw`]: #method.from_raw
+    /// it makes it back into Rust using [`CString::from_raw`]. See the safety section
+    /// in [`CString::from_raw`].
     ///
     /// # Examples
     ///
@@ -560,8 +528,6 @@ impl CString {
     ///
     /// On failure, ownership of the original `CString` is returned.
     ///
-    /// [`String`]: ../string/struct.String.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -608,10 +574,8 @@ impl CString {
         vec
     }
 
-    /// Equivalent to the [`into_bytes`] function except that the returned vector
-    /// includes the trailing nul terminator.
-    ///
-    /// [`into_bytes`]: #method.into_bytes
+    /// Equivalent to [`CString::into_bytes()`] except that the
+    /// returned vector includes the trailing nul terminator.
     ///
     /// # Examples
     ///
@@ -632,9 +596,7 @@ impl CString {
     /// The returned slice does **not** contain the trailing nul
     /// terminator, and it is guaranteed to not have any interior nul
     /// bytes. If you need the nul terminator, use
-    /// [`as_bytes_with_nul`] instead.
-    ///
-    /// [`as_bytes_with_nul`]: #method.as_bytes_with_nul
+    /// [`CString::as_bytes_with_nul`] instead.
     ///
     /// # Examples
     ///
@@ -651,10 +613,8 @@ impl CString {
         &self.inner[..self.inner.len() - 1]
     }
 
-    /// Equivalent to the [`as_bytes`] function except that the returned slice
-    /// includes the trailing nul terminator.
-    ///
-    /// [`as_bytes`]: #method.as_bytes
+    /// Equivalent to [`CString::as_bytes()`] except that the
+    /// returned slice includes the trailing nul terminator.
     ///
     /// # Examples
     ///
@@ -673,8 +633,6 @@ impl CString {
 
     /// Extracts a [`CStr`] slice containing the entire string.
     ///
-    /// [`CStr`]: struct.CStr.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -693,8 +651,6 @@ impl CString {
 
     /// Converts this `CString` into a boxed [`CStr`].
     ///
-    /// [`CStr`]: struct.CStr.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -711,8 +667,6 @@ impl CString {
     }
 
     /// Bypass "move out of struct which implements [`Drop`] trait" restriction.
-    ///
-    /// [`Drop`]: ../ops/trait.Drop.html
     fn into_inner(self) -> Box<[u8]> {
         // Rationale: `mem::forget(self)` invalidates the previous call to `ptr::read(&self.inner)`
         // so we use `ManuallyDrop` to ensure `self` is not dropped.
@@ -722,12 +676,12 @@ impl CString {
         unsafe { ptr::read(&this.inner) }
     }
 
-    /// Converts a `Vec` of `u8` to a `CString` without checking the invariants
-    /// on the given `Vec`.
+    /// Converts a [`Vec`]`<u8>` to a [`CString`] without checking the
+    /// invariants on the given [`Vec`].
     ///
     /// # Safety
     ///
-    /// The given `Vec` **must** have one nul byte as its last element.
+    /// The given [`Vec`] **must** have one nul byte as its last element.
     /// This means it cannot be empty nor have any other nul byte anywhere else.
     ///
     /// # Example
@@ -745,10 +699,10 @@ impl CString {
         Self { inner: v.into_boxed_slice() }
     }
 
-    /// Attempts to converts a `Vec` of `u8` to a `CString`.
+    /// Attempts to converts a [`Vec`]`<u8>` to a [`CString`].
     ///
     /// Runtime checks are present to ensure there is only one nul byte in the
-    /// `Vec`, its last element.
+    /// [`Vec`], its last element.
     ///
     /// # Errors
     ///
@@ -757,8 +711,8 @@ impl CString {
     ///
     /// # Examples
     ///
-    /// A successful conversion will produce the same result as [`new`] when
-    /// called without the ending nul byte.
+    /// A successful conversion will produce the same result as [`CString::new`]
+    /// when called without the ending nul byte.
     ///
     /// ```
     /// #![feature(cstring_from_vec_with_nul)]
@@ -770,7 +724,7 @@ impl CString {
     /// );
     /// ```
     ///
-    /// A incorrectly formatted vector will produce an error.
+    /// A incorrectly formatted [`Vec`] will produce an error.
     ///
     /// ```
     /// #![feature(cstring_from_vec_with_nul)]
@@ -780,8 +734,6 @@ impl CString {
     /// // No nul byte
     /// let _: FromVecWithNulError = CString::from_vec_with_nul(b"abc".to_vec()).unwrap_err();
     /// ```
-    ///
-    /// [`new`]: #method.new
     #[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")]
     pub fn from_vec_with_nul(v: Vec<u8>) -> Result<Self, FromVecWithNulError> {
         let nul_pos = memchr::memchr(0, &v);
@@ -838,9 +790,6 @@ impl From<CString> for Vec<u8> {
     /// Converts a [`CString`] into a [`Vec`]`<u8>`.
     ///
     /// The conversion consumes the [`CString`], and removes the terminating NUL byte.
-    ///
-    /// [`Vec`]: ../vec/struct.Vec.html
-    /// [`CString`]: ../ffi/struct.CString.html
     #[inline]
     fn from(s: CString) -> Vec<u8> {
         s.into_bytes()
@@ -913,9 +862,6 @@ impl From<Cow<'_, CStr>> for Box<CStr> {
 #[stable(feature = "c_string_from_box", since = "1.18.0")]
 impl From<Box<CStr>> for CString {
     /// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating.
-    ///
-    /// [`Box`]: ../boxed/struct.Box.html
-    /// [`CString`]: ../ffi/struct.CString.html
     #[inline]
     fn from(s: Box<CStr>) -> CString {
         s.into_c_string()
@@ -926,10 +872,6 @@ impl From<Box<CStr>> for CString {
 impl From<Vec<NonZeroU8>> for CString {
     /// Converts a [`Vec`]`<`[`NonZeroU8`]`>` into a [`CString`] without
     /// copying nor checking for inner null bytes.
-    ///
-    /// [`CString`]: ../ffi/struct.CString.html
-    /// [`NonZeroU8`]: ../num/struct.NonZeroU8.html
-    /// [`Vec`]: ../vec/struct.Vec.html
     #[inline]
     fn from(v: Vec<NonZeroU8>) -> CString {
         unsafe {
@@ -959,9 +901,6 @@ impl Clone for Box<CStr> {
 #[stable(feature = "box_from_c_string", since = "1.20.0")]
 impl From<CString> for Box<CStr> {
     /// Converts a [`CString`] into a [`Box`]`<CStr>` without copying or allocating.
-    ///
-    /// [`CString`]: ../ffi/struct.CString.html
-    /// [`Box`]: ../boxed/struct.Box.html
     #[inline]
     fn from(s: CString) -> Box<CStr> {
         s.into_boxed_c_str()
@@ -995,9 +934,6 @@ impl<'a> From<&'a CString> for Cow<'a, CStr> {
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<CString> for Arc<CStr> {
     /// Converts a [`CString`] into a [`Arc`]`<CStr>` without copying or allocating.
-    ///
-    /// [`CString`]: ../ffi/struct.CString.html
-    /// [`Arc`]: ../sync/struct.Arc.html
     #[inline]
     fn from(s: CString) -> Arc<CStr> {
         let arc: Arc<[u8]> = Arc::from(s.into_inner());
@@ -1017,9 +953,6 @@ impl From<&CStr> for Arc<CStr> {
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<CString> for Rc<CStr> {
     /// Converts a [`CString`] into a [`Rc`]`<CStr>` without copying or allocating.
-    ///
-    /// [`CString`]: ../ffi/struct.CString.html
-    /// [`Rc`]: ../rc/struct.Rc.html
     #[inline]
     fn from(s: CString) -> Rc<CStr> {
         let rc: Rc<[u8]> = Rc::from(s.into_inner());
@@ -1048,8 +981,6 @@ impl NulError {
     /// Returns the position of the nul byte in the slice that caused
     /// [`CString::new`] to fail.
     ///
-    /// [`CString::new`]: struct.CString.html#method.new
-    ///
     /// # Examples
     ///
     /// ```
@@ -1101,9 +1032,6 @@ impl fmt::Display for NulError {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl From<NulError> for io::Error {
     /// Converts a [`NulError`] into a [`io::Error`].
-    ///
-    /// [`NulError`]: ../ffi/struct.NulError.html
-    /// [`io::Error`]: ../io/struct.Error.html
     fn from(_: NulError) -> io::Error {
         io::Error::new(io::ErrorKind::InvalidInput, "data provided contains a nul byte")
     }
@@ -1154,8 +1082,6 @@ impl fmt::Display for FromVecWithNulError {
 impl IntoStringError {
     /// Consumes this error, returning original [`CString`] which generated the
     /// error.
-    ///
-    /// [`CString`]: struct.CString.html
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_cstring(self) -> CString {
         self.inner
@@ -1228,9 +1154,21 @@ impl CStr {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
-        let len = sys::strlen(ptr);
-        let ptr = ptr as *const u8;
-        CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
+        // SAFETY: The caller has provided a pointer that points to a valid C
+        // string with a NUL terminator of size less than `isize::MAX`, whose
+        // content remain valid and doesn't change for the lifetime of the
+        // returned `CStr`.
+        //
+        // Thus computing the length is fine (a NUL byte exists), the call to
+        // from_raw_parts is safe because we know the length is at most `isize::MAX`, meaning
+        // the call to `from_bytes_with_nul_unchecked` is correct.
+        //
+        // The cast from c_char to u8 is ok because a c_char is always one byte.
+        unsafe {
+            let len = sys::strlen(ptr);
+            let ptr = ptr as *const u8;
+            CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
+        }
     }
 
     /// Creates a C string wrapper from a byte slice.
@@ -1299,7 +1237,12 @@ impl CStr {
     #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
     #[rustc_const_unstable(feature = "const_cstr_unchecked", issue = "none")]
     pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
-        &*(bytes as *const [u8] as *const CStr)
+        // SAFETY: Casting to CStr is safe because its internal representation
+        // is a [u8] too (safe only inside std).
+        // Dereferencing the obtained pointer is safe because it comes from a
+        // reference. Making a reference is then safe because its lifetime
+        // is bound by the lifetime of the given `bytes`.
+        unsafe { &*(bytes as *const [u8] as *const CStr) }
     }
 
     /// Returns the inner pointer to this C string.
@@ -1330,7 +1273,8 @@ impl CStr {
     ///
     /// This happens because the pointer returned by `as_ptr` does not carry any
     /// lifetime information and the [`CString`] is deallocated immediately after
-    /// the `CString::new("Hello").expect("CString::new failed").as_ptr()` expression is evaluated.
+    /// the `CString::new("Hello").expect("CString::new failed").as_ptr()`
+    /// expression is evaluated.
     /// To fix the problem, bind the `CString` to a local variable:
     ///
     /// ```no_run
@@ -1345,10 +1289,8 @@ impl CStr {
     /// }
     /// ```
     ///
-    /// This way, the lifetime of the `CString` in `hello` encompasses
+    /// This way, the lifetime of the [`CString`] in `hello` encompasses
     /// the lifetime of `ptr` and the `unsafe` block.
-    ///
-    /// [`CString`]: struct.CString.html
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")]
@@ -1382,15 +1324,13 @@ impl CStr {
 
     /// Converts this C string to a byte slice containing the trailing 0 byte.
     ///
-    /// This function is the equivalent of [`to_bytes`] except that it will retain
-    /// the trailing nul terminator instead of chopping it off.
+    /// This function is the equivalent of [`CStr::to_bytes`] except that it
+    /// will retain the trailing nul terminator instead of chopping it off.
     ///
     /// > **Note**: This method is currently implemented as a 0-cost cast, but
     /// > it is planned to alter its definition in the future to perform the
     /// > length calculation whenever this method is called.
     ///
-    /// [`to_bytes`]: #method.to_bytes
-    ///
     /// # Examples
     ///
     /// ```
@@ -1411,7 +1351,7 @@ impl CStr {
     /// function will return the corresponding [`&str`] slice. Otherwise,
     /// it will return an error with details of where UTF-8 validation failed.
     ///
-    /// [`&str`]: ../primitive.str.html
+    /// [`&str`]: str
     ///
     /// # Examples
     ///
@@ -1439,12 +1379,9 @@ impl CStr {
     /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a
     /// [`Cow`]`::`[`Owned`]`(`[`String`]`)` with the result.
     ///
-    /// [`Cow`]: ../borrow/enum.Cow.html
-    /// [`Borrowed`]: ../borrow/enum.Cow.html#variant.Borrowed
-    /// [`Owned`]: ../borrow/enum.Cow.html#variant.Owned
-    /// [`str`]: ../primitive.str.html
-    /// [`String`]: ../string/struct.String.html
-    /// [U+FFFD]: ../char/constant.REPLACEMENT_CHARACTER.html
+    /// [`Borrowed`]: Cow::Borrowed
+    /// [`Owned`]: Cow::Owned
+    /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
     ///
     /// # Examples
     ///
@@ -1479,9 +1416,6 @@ impl CStr {
 
     /// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating.
     ///
-    /// [`Box`]: ../boxed/struct.Box.html
-    /// [`CString`]: struct.CString.html
-    ///
     /// # Examples
     ///
     /// ```
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index f442d7fde1a5e..0184495eecf09 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -88,7 +88,7 @@
 //! [`env::var_os()`] is used to query environment variables; it
 //! returns an [`Option`]`<`[`OsString`]`>`. If the environment variable
 //! exists you will get a [`Some`]`(os_string)`, which you can *then* try to
-//! convert to a Rust string. This yields a [`Result<>`], so that
+//! convert to a Rust string. This yields a [`Result`], so that
 //! your code can detect errors in case the environment variable did
 //! not in fact contain valid Unicode data.
 //!
@@ -124,34 +124,22 @@
 //! method is an [`OsString`] which can be round-tripped to a Windows
 //! string losslessly.
 //!
-//! [`String`]: ../string/struct.String.html
-//! [`str`]: ../primitive.str.html
-//! [`char`]: ../primitive.char.html
-//! [`u8`]: ../primitive.u8.html
-//! [`u16`]: ../primitive.u16.html
 //! [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
 //! [Unicode code point]: http://www.unicode.org/glossary/#code_point
-//! [`CString`]: struct.CString.html
-//! [`CStr`]: struct.CStr.html
-//! [`OsString`]: struct.OsString.html
-//! [`OsStr`]: struct.OsStr.html
-//! [`env::set_var()`]: ../env/fn.set_var.html
-//! [`env::var_os()`]: ../env/fn.var_os.html
-//! [`Result<>`]: ../result/enum.Result.html
-//! [unix.OsStringExt]: ../os/unix/ffi/trait.OsStringExt.html
-//! [`from_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.from_vec
-//! [`into_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.into_vec
-//! [unix.OsStrExt]: ../os/unix/ffi/trait.OsStrExt.html
-//! [`from_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.from_bytes
-//! [`as_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.as_bytes
-//! [`OsStrExt`]: ../os/unix/ffi/trait.OsStrExt.html
-//! [windows.OsStrExt]: ../os/windows/ffi/trait.OsStrExt.html
-//! [`encode_wide`]: ../os/windows/ffi/trait.OsStrExt.html#tymethod.encode_wide
-//! [`collect`]: ../iter/trait.Iterator.html#method.collect
-//! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
-//! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide
-//! [`Option`]: ../option/enum.Option.html
-//! [`Some`]: ../option/enum.Option.html#variant.Some
+//! [`env::set_var()`]: crate::env::set_var
+//! [`env::var_os()`]: crate::env::var_os
+//! [unix.OsStringExt]: crate::os::unix::ffi::OsStringExt
+//! [`from_vec`]: crate::os::unix::ffi::OsStringExt::from_vec
+//! [`into_vec`]: crate::os::unix::ffi::OsStringExt::into_vec
+//! [unix.OsStrExt]: crate::os::unix::ffi::OsStrExt
+//! [`from_bytes`]: crate::os::unix::ffi::OsStrExt::from_bytes
+//! [`as_bytes`]: crate::os::unix::ffi::OsStrExt::as_bytes
+//! [`OsStrExt`]: crate::os::unix::ffi::OsStrExt
+//! [windows.OsStrExt]: crate::os::windows::ffi::OsStrExt
+//! [`encode_wide`]: crate::os::windows::ffi::OsStrExt::encode_wide
+//! [`collect`]: crate::iter::Iterator::collect
+//! [windows.OsStringExt]: crate::os::windows::ffi::OsStringExt
+//! [`from_wide`]: crate::os::windows::ffi::OsStringExt::from_wide
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index d1eaf3c583f2d..262d39d98ee2e 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -47,14 +47,14 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
 /// create an `OsString` from a normal Rust string.
 ///
 /// **From slices:** Just like you can start with an empty Rust
-/// [`String`] and then [`push_str`][String.push_str] `&str`
+/// [`String`] and then [`String::push_str`] `&str`
 /// sub-string slices into it, you can create an empty `OsString` with
-/// the [`new`] method and then push string slices into it with the
-/// [`push`] method.
+/// the [`OsString::new`] method and then push string slices into it with the
+/// [`OsString::push`] method.
 ///
 /// # Extracting a borrowed reference to the whole OS string
 ///
-/// You can use the [`as_os_str`] method to get an `&`[`OsStr`] from
+/// You can use the [`OsString::as_os_str`] method to get an `&`[`OsStr`] from
 /// an `OsString`; this is effectively a borrowed reference to the
 /// whole string.
 ///
@@ -63,18 +63,9 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
 /// the traits which `OsString` implements for [conversions] from/to native representations.
 ///
-/// [`OsStr`]: struct.OsStr.html
-/// [`&OsStr`]: struct.OsStr.html
-/// [`CStr`]: struct.CStr.html
-/// [`From`]: ../convert/trait.From.html
-/// [`String`]: ../string/struct.String.html
-/// [`&str`]: ../primitive.str.html
-/// [`u8`]: ../primitive.u8.html
-/// [`u16`]: ../primitive.u16.html
-/// [String.push_str]: ../string/struct.String.html#method.push_str
-/// [`new`]: #method.new
-/// [`push`]: #method.push
-/// [`as_os_str`]: #method.as_os_str
+/// [`&OsStr`]: OsStr
+/// [`&str`]: str
+/// [`CStr`]: crate::ffi::CStr
 /// [conversions]: index.html#conversions
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -93,9 +84,7 @@ pub struct OsString {
 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
 /// the traits which `OsStr` implements for [conversions] from/to native representations.
 ///
-/// [`OsString`]: struct.OsString.html
-/// [`&str`]: ../primitive.str.html
-/// [`String`]: ../string/struct.String.html
+/// [`&str`]: str
 /// [conversions]: index.html#conversions
 #[stable(feature = "rust1", since = "1.0.0")]
 // FIXME:
@@ -125,8 +114,6 @@ impl OsString {
 
     /// Converts to an [`OsStr`] slice.
     ///
-    /// [`OsStr`]: struct.OsStr.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -145,8 +132,6 @@ impl OsString {
     ///
     /// On failure, ownership of the original `OsString` is returned.
     ///
-    /// [`String`]: ../../std/string/struct.String.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -163,7 +148,7 @@ impl OsString {
 
     /// Extends the string with the given [`&OsStr`] slice.
     ///
-    /// [`&OsStr`]: struct.OsStr.html
+    /// [`&OsStr`]: OsStr
     ///
     /// # Examples
     ///
@@ -333,8 +318,6 @@ impl OsString {
 
     /// Converts this `OsString` into a boxed [`OsStr`].
     ///
-    /// [`OsStr`]: struct.OsStr.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -356,8 +339,6 @@ impl From<String> for OsString {
     /// Converts a [`String`] into a [`OsString`].
     ///
     /// The conversion copies the data, and includes an allocation on the heap.
-    ///
-    /// [`OsString`]: ../../std/ffi/struct.OsString.html
     fn from(s: String) -> OsString {
         OsString { inner: Buf::from_string(s) }
     }
@@ -544,7 +525,7 @@ impl OsStr {
     ///
     /// This conversion may entail doing a check for UTF-8 validity.
     ///
-    /// [`&str`]: ../../std/primitive.str.html
+    /// [`&str`]: str
     ///
     /// # Examples
     ///
@@ -564,9 +545,7 @@ impl OsStr {
     /// Any non-Unicode sequences are replaced with
     /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
     ///
-    /// [`Cow`]: ../../std/borrow/enum.Cow.html
-    /// [`str`]: ../../std/primitive.str.html
-    /// [U+FFFD]: ../../std/char/constant.REPLACEMENT_CHARACTER.html
+    /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
     ///
     /// # Examples
     ///
@@ -613,8 +592,6 @@ impl OsStr {
 
     /// Copies the slice into an owned [`OsString`].
     ///
-    /// [`OsString`]: struct.OsString.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -662,9 +639,6 @@ impl OsStr {
     /// This number is simply useful for passing to other methods, like
     /// [`OsString::with_capacity`] to avoid reallocations.
     ///
-    /// [`OsString`]: struct.OsString.html
-    /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
-    ///
     /// # Examples
     ///
     /// ```
@@ -682,9 +656,6 @@ impl OsStr {
     }
 
     /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
-    ///
-    /// [`Box`]: ../boxed/struct.Box.html
-    /// [`OsString`]: struct.OsString.html
     #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
     pub fn into_os_string(self: Box<OsStr>) -> OsString {
         let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
@@ -706,9 +677,7 @@ impl OsStr {
     /// but non-ASCII letters are unchanged.
     ///
     /// To return a new lowercased value without modifying the existing one, use
-    /// [`to_ascii_lowercase`].
-    ///
-    /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
+    /// [`OsStr::to_ascii_lowercase`].
     ///
     /// # Examples
     ///
@@ -733,9 +702,7 @@ impl OsStr {
     /// but non-ASCII letters are unchanged.
     ///
     /// To return a new uppercased value without modifying the existing one, use
-    /// [`to_ascii_uppercase`].
-    ///
-    /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
+    /// [`OsStr::to_ascii_uppercase`].
     ///
     /// # Examples
     ///
@@ -760,9 +727,7 @@ impl OsStr {
     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
     /// but non-ASCII letters are unchanged.
     ///
-    /// To lowercase the value in-place, use [`make_ascii_lowercase`].
-    ///
-    /// [`make_ascii_lowercase`]: #method.make_ascii_lowercase
+    /// To lowercase the value in-place, use [`OsStr::make_ascii_lowercase`].
     ///
     /// # Examples
     ///
@@ -784,9 +749,7 @@ impl OsStr {
     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
     /// but non-ASCII letters are unchanged.
     ///
-    /// To uppercase the value in-place, use [`make_ascii_uppercase`].
-    ///
-    /// [`make_ascii_uppercase`]: #method.make_ascii_uppercase
+    /// To uppercase the value in-place, use [`OsStr::make_ascii_uppercase`].
     ///
     /// # Examples
     ///
@@ -865,9 +828,6 @@ impl From<Cow<'_, OsStr>> for Box<OsStr> {
 impl From<Box<OsStr>> for OsString {
     /// Converts a [`Box`]`<`[`OsStr`]`>` into a `OsString` without copying or
     /// allocating.
-    ///
-    /// [`Box`]: ../boxed/struct.Box.html
-    /// [`OsStr`]: ../ffi/struct.OsStr.html
     fn from(boxed: Box<OsStr>) -> OsString {
         boxed.into_os_string()
     }
@@ -876,9 +836,6 @@ impl From<Box<OsStr>> for OsString {
 #[stable(feature = "box_from_os_string", since = "1.20.0")]
 impl From<OsString> for Box<OsStr> {
     /// Converts a [`OsString`] into a [`Box`]`<OsStr>` without copying or allocating.
-    ///
-    /// [`Box`]: ../boxed/struct.Box.html
-    /// [`OsString`]: ../ffi/struct.OsString.html
     fn from(s: OsString) -> Box<OsStr> {
         s.into_boxed_os_str()
     }
@@ -895,9 +852,6 @@ impl Clone for Box<OsStr> {
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<OsString> for Arc<OsStr> {
     /// Converts a [`OsString`] into a [`Arc`]`<OsStr>` without copying or allocating.
-    ///
-    /// [`Arc`]: ../sync/struct.Arc.html
-    /// [`OsString`]: ../ffi/struct.OsString.html
     #[inline]
     fn from(s: OsString) -> Arc<OsStr> {
         let arc = s.inner.into_arc();
@@ -917,9 +871,6 @@ impl From<&OsStr> for Arc<OsStr> {
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<OsString> for Rc<OsStr> {
     /// Converts a [`OsString`] into a [`Rc`]`<OsStr>` without copying or allocating.
-    ///
-    /// [`Rc`]: ../rc/struct.Rc.html
-    /// [`OsString`]: ../ffi/struct.OsString.html
     #[inline]
     fn from(s: OsString) -> Rc<OsStr> {
         let rc = s.inner.into_rc();
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index ff343625a19ed..c39989a60c92b 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1813,12 +1813,190 @@ mod type_keyword {}
 
 #[doc(keyword = "unsafe")]
 //
-/// Code or interfaces whose [memory safety] cannot be verified by the type system.
+/// Code or interfaces whose [memory safety] cannot be verified by the type
+/// system.
+///
+/// The `unsafe` keyword has two uses: to declare the existence of contracts the
+/// compiler can't check (`unsafe fn` and `unsafe trait`), and to declare that a
+/// programmer has checked that these contracts have been upheld (`unsafe {}`
+/// and `unsafe impl`, but also `unsafe fn` -- see below). They are not mutually
+/// exclusive, as can be seen in `unsafe fn`.
+///
+/// # Unsafe abilities
+///
+/// **No matter what, Safe Rust can't cause Undefined Behavior**. This is
+/// referred to as [soundness]: a well-typed program actually has the desired
+/// properties. The [Nomicon][nomicon-soundness] has a more detailed explanation
+/// on the subject.
+///
+/// To ensure soundness, Safe Rust is restricted enough that it can be
+/// automatically checked. Sometimes, however, it is necessary to write code
+/// that is correct for reasons which are too clever for the compiler to
+/// understand. In those cases, you need to use Unsafe Rust.
+///
+/// Here are the abilities Unsafe Rust has in addition to Safe Rust:
+///
+/// - Dereference [raw pointers]
+/// - Implement `unsafe` [`trait`]s
+/// - Call `unsafe` functions
+/// - Mutate [`static`]s (including [`extern`]al ones)
+/// - Access fields of [`union`]s
+///
+/// However, this extra power comes with extra responsibilities: it is now up to
+/// you to ensure soundness. The `unsafe` keyword helps by clearly marking the
+/// pieces of code that need to worry about this.
+///
+/// ## The different meanings of `unsafe`
+///
+/// Not all uses of `unsafe` are equivalent: some are here to mark the existence
+/// of a contract the programmer must check, others are to say "I have checked
+/// the contract, go ahead and do this". The following
+/// [discussion on Rust Internals] has more in-depth explanations about this but
+/// here is a summary of the main points:
+///
+/// - `unsafe fn`: calling this function means abiding by a contract the
+/// compiler cannot enforce.
+/// - `unsafe trait`: implementing the [`trait`] means abiding by a
+/// contract the compiler cannot enforce.
+/// - `unsafe {}`: the contract necessary to call the operations inside the
+/// block has been checked by the programmer and is guaranteed to be respected.
+/// - `unsafe impl`: the contract necessary to implement the trait has been
+/// checked by the programmer and is guaranteed to be respected.
+///
+/// `unsafe fn` also acts like an `unsafe {}` block
+/// around the code inside the function. This means it is not just a signal to
+/// the caller, but also promises that the preconditions for the operations
+/// inside the function are upheld. Mixing these two meanings can be confusing
+/// and [proposal]s exist to use `unsafe {}` blocks inside such functions when
+/// making `unsafe` operations.
+///
+/// See the [Rustnomicon] and the [Reference] for more informations.
 ///
-/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+/// # Examples
+///
+/// ## Marking elements as `unsafe`
+///
+/// `unsafe` can be used on functions. Note that functions and statics declared
+/// in [`extern`] blocks are implicitly marked as `unsafe` (but not functions
+/// declared as `extern "something" fn ...`). Mutable statics are always unsafe,
+/// wherever they are declared. Methods can also be declared as `unsafe`:
+///
+/// ```rust
+/// # #![allow(dead_code)]
+/// static mut FOO: &str = "hello";
+///
+/// unsafe fn unsafe_fn() {}
+///
+/// extern "C" {
+///     fn unsafe_extern_fn();
+///     static BAR: *mut u32;
+/// }
+///
+/// trait SafeTraitWithUnsafeMethod {
+///     unsafe fn unsafe_method(&self);
+/// }
+///
+/// struct S;
+///
+/// impl S {
+///     unsafe fn unsafe_method_on_struct() {}
+/// }
+/// ```
+///
+/// Traits can also be declared as `unsafe`:
+///
+/// ```rust
+/// unsafe trait UnsafeTrait {}
+/// ```
 ///
+/// Since `unsafe fn` and `unsafe trait` indicate that there is a safety
+/// contract that the compiler cannot enforce, documenting it is important. The
+/// standard library has many examples of this, like the following which is an
+/// extract from [`Vec::set_len`]. The `# Safety` section explains the contract
+/// that must be fulfilled to safely call the function.
+///
+/// ```rust,ignore (stub-to-show-doc-example)
+/// /// Forces the length of the vector to `new_len`.
+/// ///
+/// /// This is a low-level operation that maintains none of the normal
+/// /// invariants of the type. Normally changing the length of a vector
+/// /// is done using one of the safe operations instead, such as
+/// /// `truncate`, `resize`, `extend`, or `clear`.
+/// ///
+/// /// # Safety
+/// ///
+/// /// - `new_len` must be less than or equal to `capacity()`.
+/// /// - The elements at `old_len..new_len` must be initialized.
+/// pub unsafe fn set_len(&mut self, new_len: usize)
+/// ```
+///
+/// ## Using `unsafe {}` blocks and `impl`s
+///
+/// Performing `unsafe` operations requires an `unsafe {}` block:
+///
+/// ```rust
+/// # #![allow(dead_code)]
+/// /// Dereference the given pointer.
+/// ///
+/// /// # Safety
+/// ///
+/// /// `ptr` must be aligned and must not be dangling.
+/// unsafe fn deref_unchecked(ptr: *const i32) -> i32 {
+///     *ptr
+/// }
+///
+/// let a = 3;
+/// let b = &a as *const _;
+/// // SAFETY: `a` has not been dropped and references are always aligned,
+/// // so `b` is a valid address.
+/// unsafe { assert_eq!(*b, deref_unchecked(b)); };
+/// ```
+///
+/// Traits marked as `unsafe` must be [`impl`]emented using `unsafe impl`. This
+/// makes a guarantee to other `unsafe` code that the implementation satisfies
+/// the trait's safety contract. The [Send] and [Sync] traits are examples of
+/// this behaviour in the standard library.
+///
+/// ```rust
+/// /// Implementors of this trait must guarantee an element is always
+/// /// accessible with index 3.
+/// unsafe trait ThreeIndexable<T> {
+///     /// Returns a reference to the element with index 3 in `&self`.
+///     fn three(&self) -> &T;
+/// }
+///
+/// // The implementation of `ThreeIndexable` for `[T; 4]` is `unsafe`
+/// // because the implementor must abide by a contract the compiler cannot
+/// // check but as a programmer we know there will always be a valid element
+/// // at index 3 to access.
+/// unsafe impl<T> ThreeIndexable<T> for [T; 4] {
+///     fn three(&self) -> &T {
+///         // SAFETY: implementing the trait means there always is an element
+///         // with index 3 accessible.
+///         unsafe { self.get_unchecked(3) }
+///     }
+/// }
+///
+/// let a = [1, 2, 4, 8];
+/// assert_eq!(a.three(), &8);
+/// ```
+///
+/// [`extern`]: keyword.extern.html
+/// [`trait`]: keyword.trait.html
+/// [`static`]: keyword.static.html
+/// [`union`]: keyword.union.html
+/// [`impl`]: keyword.impl.html
+/// [Send]: marker/trait.Send.html
+/// [Sync]: marker/trait.Sync.html
+/// [`Vec::set_len`]: vec/struct.Vec.html#method.set_len
+/// [raw pointers]: ../reference/types/pointer.html
 /// [memory safety]: ../book/ch19-01-unsafe-rust.html
-/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+/// [Rustnomicon]: ../nomicon/index.html
+/// [nomicon-soundness]: ../nomicon/safe-unsafe-meaning.html
+/// [soundness]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library
+/// [Reference]: ../reference/unsafety.html
+/// [proposal]: https://github.com/rust-lang/rfcs/pull/2585
+/// [discussion on Rust Internals]: https://internals.rust-lang.org/t/what-does-unsafe-mean/6696
 mod unsafe_keyword {}
 
 #[doc(keyword = "use")]
diff --git a/library/std/src/net/addr.rs b/library/std/src/net/addr.rs
index 8c8d1aadf48e2..4f751656e09c8 100644
--- a/library/std/src/net/addr.rs
+++ b/library/std/src/net/addr.rs
@@ -37,7 +37,7 @@ use crate::vec;
 /// assert_eq!(socket.port(), 8080);
 /// assert_eq!(socket.is_ipv4(), true);
 /// ```
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum SocketAddr {
     /// An IPv4 socket address.
@@ -597,6 +597,13 @@ impl fmt::Display for SocketAddr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Debug for SocketAddr {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self, fmt)
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for SocketAddrV4 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index 2c0025bcba069..9d7b2b807636f 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -40,7 +40,7 @@ use crate::sys_common::{AsInner, FromInner};
 /// assert_eq!(localhost_v4.is_ipv4(), true);
 /// ```
 #[stable(feature = "ip_addr", since = "1.7.0")]
-#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
 pub enum IpAddr {
     /// An IPv4 address.
     #[stable(feature = "ip_addr", since = "1.7.0")]
@@ -802,6 +802,13 @@ impl fmt::Display for IpAddr {
     }
 }
 
+#[stable(feature = "ip_addr", since = "1.7.0")]
+impl fmt::Debug for IpAddr {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self, fmt)
+    }
+}
+
 #[stable(feature = "ip_from_ip", since = "1.16.0")]
 impl From<Ipv4Addr> for IpAddr {
     /// Copies this address to a new `IpAddr::V4`.
diff --git a/library/std/src/os/raw/char.md b/library/std/src/os/raw/char.md
index 9a55767d965a6..8256b725acfa3 100644
--- a/library/std/src/os/raw/char.md
+++ b/library/std/src/os/raw/char.md
@@ -5,7 +5,5 @@ Equivalent to C's `char` type.
 C chars are most commonly used to make C strings. Unlike Rust, where the length of a string is included alongside the string, C strings mark the end of a string with the character `'\0'`. See [`CStr`] for more information.
 
 [C's `char` type]: https://en.wikipedia.org/wiki/C_data_types#Basic_types
-[Rust's `char` type]: ../../primitive.char.html
-[`CStr`]: ../../ffi/struct.CStr.html
-[`i8`]: ../../primitive.i8.html
-[`u8`]: ../../primitive.u8.html
+[Rust's `char` type]: char
+[`CStr`]: crate::ffi::CStr
diff --git a/library/std/src/os/raw/double.md b/library/std/src/os/raw/double.md
index 6818dada31793..57f4534829ec8 100644
--- a/library/std/src/os/raw/double.md
+++ b/library/std/src/os/raw/double.md
@@ -3,5 +3,4 @@ Equivalent to C's `double` type.
 This type will almost always be [`f64`], which is guaranteed to be an [IEEE-754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard.
 
 [IEEE-754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754
-[`float`]: type.c_float.html
-[`f64`]: ../../primitive.f64.html
+[`float`]: c_float
diff --git a/library/std/src/os/raw/float.md b/library/std/src/os/raw/float.md
index 57d1071d0da17..61e2abc05189d 100644
--- a/library/std/src/os/raw/float.md
+++ b/library/std/src/os/raw/float.md
@@ -3,4 +3,3 @@ Equivalent to C's `float` type.
 This type will almost always be [`f32`], which is guaranteed to be an [IEEE-754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all.
 
 [IEEE-754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754
-[`f32`]: ../../primitive.f32.html
diff --git a/library/std/src/os/raw/int.md b/library/std/src/os/raw/int.md
index a0d25fd21d89f..8062ff2307a95 100644
--- a/library/std/src/os/raw/int.md
+++ b/library/std/src/os/raw/int.md
@@ -2,6 +2,4 @@ Equivalent to C's `signed int` (`int`) type.
 
 This type will almost always be [`i32`], but may differ on some esoteric systems. The C standard technically only requires that this type be a signed integer that is at least the size of a [`short`]; some systems define it as an [`i16`], for example.
 
-[`short`]: type.c_short.html
-[`i32`]: ../../primitive.i32.html
-[`i16`]: ../../primitive.i16.html
+[`short`]: c_short
diff --git a/library/std/src/os/raw/long.md b/library/std/src/os/raw/long.md
index c620b402819fd..cc160783f78b7 100644
--- a/library/std/src/os/raw/long.md
+++ b/library/std/src/os/raw/long.md
@@ -2,6 +2,4 @@ Equivalent to C's `signed long` (`long`) type.
 
 This type will always be [`i32`] or [`i64`]. Most notably, many Linux-based systems assume an `i64`, but Windows assumes `i32`. The C standard technically only requires that this type be a signed integer that is at least 32 bits and at least the size of an [`int`], although in practice, no system would have a `long` that is neither an `i32` nor `i64`.
 
-[`int`]: type.c_int.html
-[`i32`]: ../../primitive.i32.html
-[`i64`]: ../../primitive.i64.html
+[`int`]: c_int
diff --git a/library/std/src/os/raw/longlong.md b/library/std/src/os/raw/longlong.md
index ab3d6436568df..49c61bd61f4ad 100644
--- a/library/std/src/os/raw/longlong.md
+++ b/library/std/src/os/raw/longlong.md
@@ -2,6 +2,4 @@ Equivalent to C's `signed long long` (`long long`) type.
 
 This type will almost always be [`i64`], but may differ on some systems. The C standard technically only requires that this type be a signed integer that is at least 64 bits and at least the size of a [`long`], although in practice, no system would have a `long long` that is not an `i64`, as most systems do not have a standardised [`i128`] type.
 
-[`long`]: type.c_int.html
-[`i64`]: ../../primitive.i64.html
-[`i128`]: ../../primitive.i128.html
+[`long`]: c_int
diff --git a/library/std/src/os/raw/schar.md b/library/std/src/os/raw/schar.md
index 6aa8b1211d808..69879c9f17f4d 100644
--- a/library/std/src/os/raw/schar.md
+++ b/library/std/src/os/raw/schar.md
@@ -2,5 +2,4 @@ Equivalent to C's `signed char` type.
 
 This type will always be [`i8`], but is included for completeness. It is defined as being a signed integer the same size as a C [`char`].
 
-[`char`]: type.c_char.html
-[`i8`]: ../../primitive.i8.html
+[`char`]: c_char
diff --git a/library/std/src/os/raw/short.md b/library/std/src/os/raw/short.md
index be92c6c106d59..3d1e53d1325f3 100644
--- a/library/std/src/os/raw/short.md
+++ b/library/std/src/os/raw/short.md
@@ -2,5 +2,4 @@ Equivalent to C's `signed short` (`short`) type.
 
 This type will almost always be [`i16`], but may differ on some esoteric systems. The C standard technically only requires that this type be a signed integer with at least 16 bits; some systems may define it as `i32`, for example.
 
-[`char`]: type.c_char.html
-[`i16`]: ../../primitive.i16.html
+[`char`]: c_char
diff --git a/library/std/src/os/raw/uchar.md b/library/std/src/os/raw/uchar.md
index b6ca711f86934..b633bb7f8dacf 100644
--- a/library/std/src/os/raw/uchar.md
+++ b/library/std/src/os/raw/uchar.md
@@ -2,5 +2,4 @@ Equivalent to C's `unsigned char` type.
 
 This type will always be [`u8`], but is included for completeness. It is defined as being an unsigned integer the same size as a C [`char`].
 
-[`char`]: type.c_char.html
-[`u8`]: ../../primitive.u8.html
+[`char`]: c_char
diff --git a/library/std/src/os/raw/uint.md b/library/std/src/os/raw/uint.md
index 6f7013a8ac18d..f3abea35937ab 100644
--- a/library/std/src/os/raw/uint.md
+++ b/library/std/src/os/raw/uint.md
@@ -2,6 +2,4 @@ Equivalent to C's `unsigned int` type.
 
 This type will almost always be [`u32`], but may differ on some esoteric systems. The C standard technically only requires that this type be an unsigned integer with the same size as an [`int`]; some systems define it as a [`u16`], for example.
 
-[`int`]: type.c_int.html
-[`u32`]: ../../primitive.u32.html
-[`u16`]: ../../primitive.u16.html
+[`int`]: c_int
diff --git a/library/std/src/os/raw/ulong.md b/library/std/src/os/raw/ulong.md
index c350395080e80..4ab304e657773 100644
--- a/library/std/src/os/raw/ulong.md
+++ b/library/std/src/os/raw/ulong.md
@@ -2,6 +2,4 @@ Equivalent to C's `unsigned long` type.
 
 This type will always be [`u32`] or [`u64`]. Most notably, many Linux-based systems assume an `u64`, but Windows assumes `u32`. The C standard technically only requires that this type be an unsigned integer with the size of a [`long`], although in practice, no system would have a `ulong` that is neither a `u32` nor `u64`.
 
-[`long`]: type.c_long.html
-[`u32`]: ../../primitive.u32.html
-[`u64`]: ../../primitive.u64.html
+[`long`]: c_long
diff --git a/library/std/src/os/raw/ulonglong.md b/library/std/src/os/raw/ulonglong.md
index c41faf74c5c68..a27d70e17537d 100644
--- a/library/std/src/os/raw/ulonglong.md
+++ b/library/std/src/os/raw/ulonglong.md
@@ -2,6 +2,4 @@ Equivalent to C's `unsigned long long` type.
 
 This type will almost always be [`u64`], but may differ on some systems. The C standard technically only requires that this type be an unsigned integer with the size of a [`long long`], although in practice, no system would have a `long long` that is not a `u64`, as most systems do not have a standardised [`u128`] type.
 
-[`long long`]: type.c_longlong.html
-[`u64`]: ../../primitive.u64.html
-[`u128`]: ../../primitive.u128.html
+[`long long`]: c_longlong
diff --git a/library/std/src/os/raw/ushort.md b/library/std/src/os/raw/ushort.md
index d364abb3c8e0c..6928e51b352c8 100644
--- a/library/std/src/os/raw/ushort.md
+++ b/library/std/src/os/raw/ushort.md
@@ -2,5 +2,4 @@ Equivalent to C's `unsigned short` type.
 
 This type will almost always be [`u16`], but may differ on some esoteric systems. The C standard technically only requires that this type be an unsigned integer with the same size as a [`short`].
 
-[`short`]: type.c_short.html
-[`u16`]: ../../primitive.u16.html
+[`short`]: c_short
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 4ba1940fd0ece..6d94fa9ebfe6d 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -84,25 +84,15 @@
 //! assert_eq!(b"test", output.stdout.as_slice());
 //! ```
 //!
-//! [`abort`]: fn.abort.html
-//! [`exit`]: fn.exit.html
+//! [`spawn`]: Command::spawn
+//! [`output`]: Command::output
 //!
-//! [`Command`]: struct.Command.html
-//! [`spawn`]: struct.Command.html#method.spawn
-//! [`output`]: struct.Command.html#method.output
+//! [`stdout`]: Command::stdout
+//! [`stdin`]: Command::stdin
+//! [`stderr`]: Command::stderr
 //!
-//! [`Child`]: struct.Child.html
-//! [`ChildStdin`]: struct.ChildStdin.html
-//! [`ChildStdout`]: struct.ChildStdout.html
-//! [`ChildStderr`]: struct.ChildStderr.html
-//! [`Stdio`]: struct.Stdio.html
-//!
-//! [`stdout`]: struct.Command.html#method.stdout
-//! [`stdin`]: struct.Command.html#method.stdin
-//! [`stderr`]: struct.Command.html#method.stderr
-//!
-//! [`Write`]: ../io/trait.Write.html
-//! [`Read`]: ../io/trait.Read.html
+//! [`Write`]: io::Write
+//! [`Read`]: io::Read
 
 #![stable(feature = "process", since = "1.0.0")]
 
@@ -130,7 +120,7 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 /// run, even after the `Child` handle to the child process has gone out of
 /// scope.
 ///
-/// Calling [`wait`](#method.wait) (or other functions that wrap around it) will make
+/// Calling [`wait`] (or other functions that wrap around it) will make
 /// the parent process wait until the child has actually exited before
 /// continuing.
 ///
@@ -162,25 +152,44 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 /// assert!(ecode.success());
 /// ```
 ///
-/// [`Command`]: struct.Command.html
-/// [`Drop`]: ../../core/ops/trait.Drop.html
-/// [`wait`]: #method.wait
+/// [`wait`]: Child::wait
 #[stable(feature = "process", since = "1.0.0")]
 pub struct Child {
     handle: imp::Process,
 
     /// The handle for writing to the child's standard input (stdin), if it has
-    /// been captured.
+    /// been captured. To avoid partially moving
+    /// the `child` and thus blocking yourself from calling
+    /// functions on `child` while using `stdin`,
+    /// you might find it helpful:
+    ///
+    /// ```compile_fail,E0425
+    /// let stdin = child.stdin.take().unwrap();
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub stdin: Option<ChildStdin>,
 
     /// The handle for reading from the child's standard output (stdout), if it
-    /// has been captured.
+    /// has been captured. You might find it helpful to do
+    ///
+    /// ```compile_fail,E0425
+    /// let stdout = child.stdout.take().unwrap();
+    /// ```
+    ///
+    /// to avoid partially moving the `child` and thus blocking yourself from calling
+    /// functions on `child` while using `stdout`.
     #[stable(feature = "process", since = "1.0.0")]
     pub stdout: Option<ChildStdout>,
 
     /// The handle for reading from the child's standard error (stderr), if it
-    /// has been captured.
+    /// has been captured. You might find it helpful to do
+    ///
+    /// ```compile_fail,E0425
+    /// let stderr = child.stderr.take().unwrap();
+    /// ```
+    ///
+    /// to avoid partially moving the `child` and thus blocking yourself from calling
+    /// functions on `child` while using `stderr`.
     #[stable(feature = "process", since = "1.0.0")]
     pub stderr: Option<ChildStderr>,
 }
@@ -227,9 +236,8 @@ impl fmt::Debug for Child {
 /// file handle will be closed. If the child process was blocked on input prior
 /// to being dropped, it will become unblocked after dropping.
 ///
-/// [`Child`]: struct.Child.html
-/// [`stdin`]: struct.Child.html#structfield.stdin
-/// [dropped]: ../ops/trait.Drop.html
+/// [`stdin`]: Child::stdin
+/// [dropped]: Drop
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStdin {
     inner: AnonPipe,
@@ -286,9 +294,8 @@ impl fmt::Debug for ChildStdin {
 /// When an instance of `ChildStdout` is [dropped], the `ChildStdout`'s
 /// underlying file handle will be closed.
 ///
-/// [`Child`]: struct.Child.html
-/// [`stdout`]: struct.Child.html#structfield.stdout
-/// [dropped]: ../ops/trait.Drop.html
+/// [`stdout`]: Child::stdout
+/// [dropped]: Drop
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStdout {
     inner: AnonPipe,
@@ -347,9 +354,8 @@ impl fmt::Debug for ChildStdout {
 /// When an instance of `ChildStderr` is [dropped], the `ChildStderr`'s
 /// underlying file handle will be closed.
 ///
-/// [`Child`]: struct.Child.html
-/// [`stderr`]: struct.Child.html#structfield.stderr
-/// [dropped]: ../ops/trait.Drop.html
+/// [`stderr`]: Child::stderr
+/// [dropped]: Drop
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStderr {
     inner: AnonPipe,
@@ -522,7 +528,7 @@ impl Command {
     ///
     /// To pass multiple arguments see [`args`].
     ///
-    /// [`args`]: #method.args
+    /// [`args`]: Command::args
     ///
     /// # Examples
     ///
@@ -547,7 +553,7 @@ impl Command {
     ///
     /// To pass a single argument see [`arg`].
     ///
-    /// [`arg`]: #method.arg
+    /// [`arg`]: Command::arg
     ///
     /// # Examples
     ///
@@ -700,7 +706,7 @@ impl Command {
     ///         .expect("ls command failed to start");
     /// ```
     ///
-    /// [`canonicalize`]: ../fs/fn.canonicalize.html
+    /// [`canonicalize`]: crate::fs::canonicalize
     #[stable(feature = "process", since = "1.0.0")]
     pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
         self.inner.cwd(dir.as_ref().as_ref());
@@ -712,8 +718,8 @@ impl Command {
     /// Defaults to [`inherit`] when used with `spawn` or `status`, and
     /// defaults to [`piped`] when used with `output`.
     ///
-    /// [`inherit`]: struct.Stdio.html#method.inherit
-    /// [`piped`]: struct.Stdio.html#method.piped
+    /// [`inherit`]: Stdio::inherit
+    /// [`piped`]: Stdio::piped
     ///
     /// # Examples
     ///
@@ -738,8 +744,8 @@ impl Command {
     /// Defaults to [`inherit`] when used with `spawn` or `status`, and
     /// defaults to [`piped`] when used with `output`.
     ///
-    /// [`inherit`]: struct.Stdio.html#method.inherit
-    /// [`piped`]: struct.Stdio.html#method.piped
+    /// [`inherit`]: Stdio::inherit
+    /// [`piped`]: Stdio::piped
     ///
     /// # Examples
     ///
@@ -764,8 +770,8 @@ impl Command {
     /// Defaults to [`inherit`] when used with `spawn` or `status`, and
     /// defaults to [`piped`] when used with `output`.
     ///
-    /// [`inherit`]: struct.Stdio.html#method.inherit
-    /// [`piped`]: struct.Stdio.html#method.piped
+    /// [`inherit`]: Stdio::inherit
+    /// [`piped`]: Stdio::piped
     ///
     /// # Examples
     ///
@@ -893,10 +899,8 @@ impl AsInnerMut<imp::Command> for Command {
 /// [`Command`], or the [`wait_with_output`] method of a [`Child`]
 /// process.
 ///
-/// [`Command`]: struct.Command.html
-/// [`Child`]: struct.Child.html
-/// [`output`]: struct.Command.html#method.output
-/// [`wait_with_output`]: struct.Child.html#method.wait_with_output
+/// [`output`]: Command::output
+/// [`wait_with_output`]: Child::wait_with_output
 #[derive(PartialEq, Eq, Clone)]
 #[stable(feature = "process", since = "1.0.0")]
 pub struct Output {
@@ -939,10 +943,9 @@ impl fmt::Debug for Output {
 /// Describes what to do with a standard I/O stream for a child process when
 /// passed to the [`stdin`], [`stdout`], and [`stderr`] methods of [`Command`].
 ///
-/// [`stdin`]: struct.Command.html#method.stdin
-/// [`stdout`]: struct.Command.html#method.stdout
-/// [`stderr`]: struct.Command.html#method.stderr
-/// [`Command`]: struct.Command.html
+/// [`stdin`]: Command::stdin
+/// [`stdout`]: Command::stdout
+/// [`stderr`]: Command::stderr
 #[stable(feature = "process", since = "1.0.0")]
 pub struct Stdio(imp::Stdio);
 
@@ -1206,10 +1209,8 @@ impl From<fs::File> for Stdio {
 /// status is exposed through the [`status`] method, or the [`wait`] method
 /// of a [`Child`] process.
 ///
-/// [`Command`]: struct.Command.html
-/// [`Child`]: struct.Child.html
-/// [`status`]: struct.Command.html#method.status
-/// [`wait`]: struct.Child.html#method.wait
+/// [`status`]: Command::status
+/// [`wait`]: Child::wait
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ExitStatus(imp::ExitStatus);
@@ -1294,8 +1295,8 @@ impl fmt::Display for ExitStatus {
 /// For the platform's canonical successful and unsuccessful codes, see
 /// the [`SUCCESS`] and [`FAILURE`] associated items.
 ///
-/// [`SUCCESS`]: #associatedconstant.SUCCESS
-/// [`FAILURE`]: #associatedconstant.FAILURE
+/// [`SUCCESS`]: ExitCode::SUCCESS
+/// [`FAILURE`]: ExitCode::FAILURE
 ///
 /// **Warning**: While various forms of this were discussed in [RFC #1937],
 /// it was ultimately cut from that RFC, and thus this type is more subject
@@ -1349,9 +1350,9 @@ impl Child {
     /// }
     /// ```
     ///
-    /// [`ErrorKind`]: ../io/enum.ErrorKind.html
-    /// [`InvalidInput`]: ../io/enum.ErrorKind.html#variant.InvalidInput
-    /// [`Other`]: ../io/enum.ErrorKind.html#variant.Other
+    /// [`ErrorKind`]: io::ErrorKind
+    /// [`InvalidInput`]: io::ErrorKind::InvalidInput
+    /// [`Other`]: io::ErrorKind::Other
     #[stable(feature = "process", since = "1.0.0")]
     pub fn kill(&mut self) -> io::Result<()> {
         self.handle.kill()
@@ -1616,8 +1617,7 @@ pub fn exit(code: i32) -> ! {
 /// }
 /// ```
 ///
-/// [`panic!`]: ../../std/macro.panic.html
-/// [panic hook]: ../../std/panic/fn.set_hook.html
+/// [panic hook]: crate::panic::set_hook
 #[stable(feature = "process_abort", since = "1.17.0")]
 pub fn abort() -> ! {
     crate::sys::abort_internal();
diff --git a/src/librustc_ast/visit.rs b/src/librustc_ast/visit.rs
index 2c3d1e97df975..b65a88cb90e88 100644
--- a/src/librustc_ast/visit.rs
+++ b/src/librustc_ast/visit.rs
@@ -50,6 +50,13 @@ impl<'a> FnKind<'a> {
         }
     }
 
+    pub fn ident(&self) -> Option<&Ident> {
+        match self {
+            FnKind::Fn(_, ident, ..) => Some(ident),
+            _ => None,
+        }
+    }
+
     pub fn decl(&self) -> &'a FnDecl {
         match self {
             FnKind::Fn(_, _, sig, _, _) => &sig.decl,
diff --git a/src/librustc_error_codes/error_codes/E0752.md b/src/librustc_error_codes/error_codes/E0752.md
index 86945f83b5524..9736da80c2b7b 100644
--- a/src/librustc_error_codes/error_codes/E0752.md
+++ b/src/librustc_error_codes/error_codes/E0752.md
@@ -1,11 +1,19 @@
-`fn main()` or the specified start function is not allowed to be
-async. You might be seeing this error because your async runtime
-library is not set up correctly.
+The entry point of the program was marked as `async`.
 
 Erroneous code example:
 
 ```compile_fail,E0752
-async fn main() -> Result<i32, ()> {
-    Ok(1)
+async fn main() -> Result<(), ()> { // error!
+    Ok(())
+}
+```
+
+`fn main()` or the specified start function is not allowed to be `async`. Not
+having a correct async runtime library setup may cause this error. To fix it,
+declare the entry point without `async`:
+
+```
+fn main() -> Result<(), ()> { // ok!
+    Ok(())
 }
 ```
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index 7fbe5c409d3ce..4101f70b8206d 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -57,6 +57,12 @@ fn eval_body_using_ecx<'mir, 'tcx>(
     ecx.run()?;
 
     // Intern the result
+    // FIXME: since the DefId of a promoted is the DefId of its owner, this
+    // means that promoteds in statics are actually interned like statics!
+    // However, this is also currently crucial because we promote mutable
+    // non-empty slices in statics to extend their lifetime, and this
+    // ensures that they are put into a mutable allocation.
+    // For other kinds of promoteds in statics (like array initializers), this is rather silly.
     let intern_kind = match tcx.static_mutability(cid.instance.def_id()) {
         Some(m) => InternKind::Static(m),
         None if cid.promoted.is_some() => InternKind::Promoted,
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index dffbc969c21b8..6c8ee72bc66c2 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -312,7 +312,8 @@ pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx>>(
     let tcx = ecx.tcx;
     let base_intern_mode = match intern_kind {
         InternKind::Static(mutbl) => InternMode::Static(mutbl),
-        // FIXME: what about array lengths, array initializers?
+        // `Constant` includes array lengths.
+        // `Promoted` includes non-`Copy` array initializers and `rustc_args_required_const` arguments.
         InternKind::Constant | InternKind::Promoted => InternMode::ConstBase,
     };
 
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index c056410570157..94637bae44a78 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -101,7 +101,7 @@ impl TempState {
 /// of a larger candidate.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum Candidate {
-    /// Borrow of a constant temporary.
+    /// Borrow of a constant temporary, candidate for lifetime extension.
     Ref(Location),
 
     /// Promotion of the `x` in `[x; 32]`.
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index a7d3697405751..b3746ac2db2bd 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -7,6 +7,7 @@ use crate::{PathResult, PathSource, Segment};
 
 use rustc_ast::ast::{self, Expr, ExprKind, Item, ItemKind, NodeId, Path, Ty, TyKind};
 use rustc_ast::util::lev_distance::find_best_match_for_name;
+use rustc_ast::visit::FnKind;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
@@ -175,16 +176,40 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
         let code = source.error_code(res.is_some());
         let mut err = self.r.session.struct_span_err_with_code(base_span, &base_msg, code);
 
+        let is_assoc_fn = self.self_type_is_available(span);
         // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
-        if ["this", "my"].contains(&&*item_str.as_str())
-            && self.self_value_is_available(path[0].ident.span, span)
-        {
+        if ["this", "my"].contains(&&*item_str.as_str()) && is_assoc_fn {
             err.span_suggestion_short(
                 span,
                 "you might have meant to use `self` here instead",
                 "self".to_string(),
                 Applicability::MaybeIncorrect,
             );
+            if !self.self_value_is_available(path[0].ident.span, span) {
+                if let Some((FnKind::Fn(_, _, sig, ..), fn_span)) =
+                    &self.diagnostic_metadata.current_function
+                {
+                    let (span, sugg) = if let Some(param) = sig.decl.inputs.get(0) {
+                        (param.span.shrink_to_lo(), "&self, ")
+                    } else {
+                        (
+                            self.r
+                                .session
+                                .source_map()
+                                .span_through_char(*fn_span, '(')
+                                .shrink_to_hi(),
+                            "&self",
+                        )
+                    };
+                    err.span_suggestion_verbose(
+                        span,
+                        "if you meant to use `self`, you are also missing a `self` receiver \
+                         argument",
+                        sugg.to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+            }
         }
 
         // Emit special messages for unresolved `Self` and `self`.
@@ -213,7 +238,38 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
                 if fn_kind.decl().inputs.get(0).map(|p| p.is_self()).unwrap_or(false) {
                     err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
                 } else {
-                    err.span_label(*span, "this function doesn't have a `self` parameter");
+                    let doesnt = if is_assoc_fn {
+                        let (span, sugg) = fn_kind
+                            .decl()
+                            .inputs
+                            .get(0)
+                            .map(|p| (p.span.shrink_to_lo(), "&self, "))
+                            .unwrap_or_else(|| {
+                                (
+                                    self.r
+                                        .session
+                                        .source_map()
+                                        .span_through_char(*span, '(')
+                                        .shrink_to_hi(),
+                                    "&self",
+                                )
+                            });
+                        err.span_suggestion_verbose(
+                            span,
+                            "add a `self` receiver parameter to make the associated `fn` a method",
+                            sugg.to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                        "doesn't"
+                    } else {
+                        "can't"
+                    };
+                    if let Some(ident) = fn_kind.ident() {
+                        err.span_label(
+                            ident.span,
+                            &format!("this function {} have a `self` parameter", doesnt),
+                        );
+                    }
                 }
             }
             return (err, Vec::new());
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 2be100ae33662..3093ddbeaf1ae 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1623,6 +1623,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         span: Span,
         trait_bounds: &[hir::PolyTraitRef<'_>],
         lifetime: &hir::Lifetime,
+        borrowed: bool,
     ) -> Ty<'tcx> {
         let tcx = self.tcx();
 
@@ -1837,15 +1838,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     self.ast_region_to_region(lifetime, None)
                 } else {
                     self.re_infer(None, span).unwrap_or_else(|| {
-                        // FIXME: these can be redundant with E0106, but not always.
-                        struct_span_err!(
+                        let mut err = struct_span_err!(
                             tcx.sess,
                             span,
                             E0228,
                             "the lifetime bound for this object type cannot be deduced \
                              from context; please supply an explicit bound"
-                        )
-                        .emit();
+                        );
+                        if borrowed {
+                            // We will have already emitted an error E0106 complaining about a
+                            // missing named lifetime in `&dyn Trait`, so we elide this one.
+                            err.delay_as_bug();
+                        } else {
+                            err.emit();
+                        }
                         tcx.lifetimes.re_static
                     })
                 }
@@ -2873,6 +2879,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     /// Parses the programmer's textual representation of a type into our
     /// internal notion of a type.
     pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
+        self.ast_ty_to_ty_inner(ast_ty, false)
+    }
+
+    /// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait
+    /// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors.
+    fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool) -> Ty<'tcx> {
         debug!("ast_ty_to_ty(id={:?}, ast_ty={:?} ty_ty={:?})", ast_ty.hir_id, ast_ty, ast_ty.kind);
 
         let tcx = self.tcx();
@@ -2885,7 +2897,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             hir::TyKind::Rptr(ref region, ref mt) => {
                 let r = self.ast_region_to_region(region, None);
                 debug!("ast_ty_to_ty: r={:?}", r);
-                let t = self.ast_ty_to_ty(&mt.ty);
+                let t = self.ast_ty_to_ty_inner(&mt.ty, true);
                 tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl })
             }
             hir::TyKind::Never => tcx.types.never,
@@ -2903,7 +2915,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 ))
             }
             hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
-                self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
+                self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed)
             }
             hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
                 debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
diff --git a/src/test/ui/error-codes/E0424.rs b/src/test/ui/error-codes/E0424.rs
index 3c6a1d4f88f11..fa0c86ecf4894 100644
--- a/src/test/ui/error-codes/E0424.rs
+++ b/src/test/ui/error-codes/E0424.rs
@@ -6,6 +6,10 @@ impl Foo {
     fn foo() {
         self.bar(); //~ ERROR E0424
     }
+
+    fn baz(_: i32) {
+        self.bar(); //~ ERROR E0424
+    }
 }
 
 fn main () {
diff --git a/src/test/ui/error-codes/E0424.stderr b/src/test/ui/error-codes/E0424.stderr
index 690a101496d73..9b8a29e827249 100644
--- a/src/test/ui/error-codes/E0424.stderr
+++ b/src/test/ui/error-codes/E0424.stderr
@@ -1,21 +1,37 @@
 error[E0424]: expected value, found module `self`
   --> $DIR/E0424.rs:7:9
    |
-LL | /     fn foo() {
-LL | |         self.bar();
-   | |         ^^^^ `self` value is a keyword only available in methods with a `self` parameter
-LL | |     }
-   | |_____- this function doesn't have a `self` parameter
+LL |     fn foo() {
+   |        --- this function doesn't have a `self` parameter
+LL |         self.bar();
+   |         ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+   |
+help: add a `self` receiver parameter to make the associated `fn` a method
+   |
+LL |     fn foo(&self) {
+   |            ^^^^^
+
+error[E0424]: expected value, found module `self`
+  --> $DIR/E0424.rs:11:9
+   |
+LL |     fn baz(_: i32) {
+   |        --- this function doesn't have a `self` parameter
+LL |         self.bar();
+   |         ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+   |
+help: add a `self` receiver parameter to make the associated `fn` a method
+   |
+LL |     fn baz(&self, _: i32) {
+   |            ^^^^^^
 
 error[E0424]: expected unit struct, unit variant or constant, found module `self`
-  --> $DIR/E0424.rs:12:9
+  --> $DIR/E0424.rs:16:9
    |
-LL | / fn main () {
-LL | |     let self = "self";
-   | |         ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
-LL | | }
-   | |_- this function doesn't have a `self` parameter
+LL | fn main () {
+   |    ---- this function can't have a `self` parameter
+LL |     let self = "self";
+   |         ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0424`.
diff --git a/src/test/ui/issues/issue-5099.rs b/src/test/ui/issues/issue-5099.rs
index d00fff3280920..ee134835c37ed 100644
--- a/src/test/ui/issues/issue-5099.rs
+++ b/src/test/ui/issues/issue-5099.rs
@@ -1,3 +1,10 @@
-trait B < A > { fn a() -> A { this.a } } //~ ERROR cannot find value `this` in this scope
+trait B <A> {
+    fn a() -> A {
+        this.a //~ ERROR cannot find value `this` in this scope
+    }
+    fn b(x: i32) {
+        this.b(x); //~ ERROR cannot find value `this` in this scope
+    }
+}
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-5099.stderr b/src/test/ui/issues/issue-5099.stderr
index cc11db9c5eca6..b52fd28b2b575 100644
--- a/src/test/ui/issues/issue-5099.stderr
+++ b/src/test/ui/issues/issue-5099.stderr
@@ -1,9 +1,33 @@
 error[E0425]: cannot find value `this` in this scope
-  --> $DIR/issue-5099.rs:1:31
+  --> $DIR/issue-5099.rs:3:9
    |
-LL | trait B < A > { fn a() -> A { this.a } }
-   |                               ^^^^ not found in this scope
+LL |         this.a
+   |         ^^^^ not found in this scope
+   |
+help: you might have meant to use `self` here instead
+   |
+LL |         self.a
+   |         ^^^^
+help: if you meant to use `self`, you are also missing a `self` receiver argument
+   |
+LL |     fn a(&self) -> A {
+   |          ^^^^^
+
+error[E0425]: cannot find value `this` in this scope
+  --> $DIR/issue-5099.rs:6:9
+   |
+LL |         this.b(x);
+   |         ^^^^ not found in this scope
+   |
+help: you might have meant to use `self` here instead
+   |
+LL |         self.b(x);
+   |         ^^^^
+help: if you meant to use `self`, you are also missing a `self` receiver argument
+   |
+LL |     fn b(&self, x: i32) {
+   |          ^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/resolve/issue-2356.stderr b/src/test/ui/resolve/issue-2356.stderr
index b687f0b0af0ad..0339daa0d6a18 100644
--- a/src/test/ui/resolve/issue-2356.stderr
+++ b/src/test/ui/resolve/issue-2356.stderr
@@ -70,14 +70,15 @@ LL |         purr();
 error[E0424]: expected value, found module `self`
   --> $DIR/issue-2356.rs:65:8
    |
-LL | /   fn meow() {
-LL | |     if self.whiskers > 3 {
-   | |        ^^^^ `self` value is a keyword only available in methods with a `self` parameter
-LL | |
-LL | |         println!("MEOW");
-LL | |     }
-LL | |   }
-   | |___- this function doesn't have a `self` parameter
+LL |   fn meow() {
+   |      ---- this function doesn't have a `self` parameter
+LL |     if self.whiskers > 3 {
+   |        ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+   |
+help: add a `self` receiver parameter to make the associated `fn` a method
+   |
+LL |   fn meow(&self) {
+   |           ^^^^^
 
 error[E0425]: cannot find function `grow_older` in this scope
   --> $DIR/issue-2356.rs:72:5
@@ -112,12 +113,10 @@ LL |     purr_louder();
 error[E0424]: expected value, found module `self`
   --> $DIR/issue-2356.rs:92:5
    |
-LL | / fn main() {
-LL | |     self += 1;
-   | |     ^^^^ `self` value is a keyword only available in methods with a `self` parameter
-LL | |
-LL | | }
-   | |_- this function doesn't have a `self` parameter
+LL | fn main() {
+   |    ---- this function can't have a `self` parameter
+LL |     self += 1;
+   |     ^^^^ `self` value is a keyword only available in methods with a `self` parameter
 
 error: aborting due to 17 previous errors
 
diff --git a/src/test/ui/suggestions/missing-lifetime-specifier.rs b/src/test/ui/suggestions/missing-lifetime-specifier.rs
index b09c1879d7015..fe88d105c78bf 100644
--- a/src/test/ui/suggestions/missing-lifetime-specifier.rs
+++ b/src/test/ui/suggestions/missing-lifetime-specifier.rs
@@ -25,8 +25,6 @@ thread_local! {
     //~| ERROR missing lifetime specifier
     //~| ERROR missing lifetime specifier
     //~| ERROR missing lifetime specifier
-    //~| ERROR the lifetime bound for this object type cannot be deduced from context
-    //~| ERROR the lifetime bound for this object type cannot be deduced from context
 }
 thread_local! {
     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
@@ -39,8 +37,6 @@ thread_local! {
     //~| ERROR missing lifetime specifier
     //~| ERROR missing lifetime specifier
     //~| ERROR missing lifetime specifier
-    //~| ERROR the lifetime bound for this object type cannot be deduced from context
-    //~| ERROR the lifetime bound for this object type cannot be deduced from context
 }
 
 thread_local! {
@@ -52,9 +48,7 @@ thread_local! {
 }
 thread_local! {
     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
-    //~^ ERROR the lifetime bound for this object type cannot be deduced from context
-    //~| ERROR the lifetime bound for this object type cannot be deduced from context
-    //~| ERROR wrong number of lifetime arguments: expected 2, found 1
+    //~^ ERROR wrong number of lifetime arguments: expected 2, found 1
     //~| ERROR wrong number of lifetime arguments: expected 2, found 1
     //~| ERROR wrong number of lifetime arguments: expected 2, found 1
     //~| ERROR wrong number of lifetime arguments: expected 2, found 1
diff --git a/src/test/ui/suggestions/missing-lifetime-specifier.stderr b/src/test/ui/suggestions/missing-lifetime-specifier.stderr
index 2630cf1affae6..9838ac72ad767 100644
--- a/src/test/ui/suggestions/missing-lifetime-specifier.stderr
+++ b/src/test/ui/suggestions/missing-lifetime-specifier.stderr
@@ -71,7 +71,7 @@ LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar<'static, 'static>>>>> = Ref
    |                                             ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:32:48
+  --> $DIR/missing-lifetime-specifier.rs:30:48
    |
 LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
    |                                                ^ expected 2 lifetime parameters
@@ -83,7 +83,7 @@ LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> =
    |                                                ^^^^^^^^^^^^^^^^^
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:32:48
+  --> $DIR/missing-lifetime-specifier.rs:30:48
    |
 LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
    |                                                ^ expected 2 lifetime parameters
@@ -95,7 +95,7 @@ LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> =
    |                                                ^^^^^^^^^^^^^^^^^
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-specifier.rs:37:44
+  --> $DIR/missing-lifetime-specifier.rs:35:44
    |
 LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^ expected named lifetime parameter
@@ -107,7 +107,7 @@ LL |     static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<i32>>>>> = RefCell:
    |                                            ^^^^^^^^
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:37:49
+  --> $DIR/missing-lifetime-specifier.rs:35:49
    |
 LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
    |                                                 ^ expected 2 lifetime parameters
@@ -119,7 +119,7 @@ LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>>
    |                                                 ^^^^^^^^^^^^^^^^^
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-specifier.rs:37:44
+  --> $DIR/missing-lifetime-specifier.rs:35:44
    |
 LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^ expected named lifetime parameter
@@ -131,7 +131,7 @@ LL |     static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<i32>>>>> = RefCell:
    |                                            ^^^^^^^^
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:37:49
+  --> $DIR/missing-lifetime-specifier.rs:35:49
    |
 LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
    |                                                 ^ expected 2 lifetime parameters
@@ -143,7 +143,7 @@ LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>>
    |                                                 ^^^^^^^^^^^^^^^^^
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-specifier.rs:54:44
+  --> $DIR/missing-lifetime-specifier.rs:50:44
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^ expected named lifetime parameter
@@ -155,7 +155,7 @@ LL |     static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> =
    |                                            ^^^^^^^^
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-specifier.rs:54:44
+  --> $DIR/missing-lifetime-specifier.rs:50:44
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^ expected named lifetime parameter
@@ -166,91 +166,55 @@ help: consider using the `'static` lifetime
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^^^^^^^^
 
-error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
-  --> $DIR/missing-lifetime-specifier.rs:23:45
-   |
-LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
-   |                                             ^^^
-
-error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
-  --> $DIR/missing-lifetime-specifier.rs:23:45
-   |
-LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
-   |                                             ^^^
-
-error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
-  --> $DIR/missing-lifetime-specifier.rs:37:45
-   |
-LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
-   |                                             ^^^^^^^^
-
-error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
-  --> $DIR/missing-lifetime-specifier.rs:37:45
-   |
-LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
-   |                                             ^^^^^^^^
-
 error[E0107]: wrong number of lifetime arguments: expected 2, found 1
-  --> $DIR/missing-lifetime-specifier.rs:47:44
+  --> $DIR/missing-lifetime-specifier.rs:43:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
 
 error[E0107]: wrong number of lifetime arguments: expected 2, found 1
-  --> $DIR/missing-lifetime-specifier.rs:47:44
+  --> $DIR/missing-lifetime-specifier.rs:43:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
 
 error[E0107]: wrong number of lifetime arguments: expected 2, found 1
-  --> $DIR/missing-lifetime-specifier.rs:47:44
+  --> $DIR/missing-lifetime-specifier.rs:43:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
 
 error[E0107]: wrong number of lifetime arguments: expected 2, found 1
-  --> $DIR/missing-lifetime-specifier.rs:47:44
+  --> $DIR/missing-lifetime-specifier.rs:43:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
 
 error[E0107]: wrong number of lifetime arguments: expected 2, found 1
-  --> $DIR/missing-lifetime-specifier.rs:54:45
+  --> $DIR/missing-lifetime-specifier.rs:50:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                             ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
 
 error[E0107]: wrong number of lifetime arguments: expected 2, found 1
-  --> $DIR/missing-lifetime-specifier.rs:54:45
+  --> $DIR/missing-lifetime-specifier.rs:50:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                             ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
 
-error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
-  --> $DIR/missing-lifetime-specifier.rs:54:45
-   |
-LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
-   |                                             ^^^^^^^^^^^^^^^^^
-
 error[E0107]: wrong number of lifetime arguments: expected 2, found 1
-  --> $DIR/missing-lifetime-specifier.rs:54:45
+  --> $DIR/missing-lifetime-specifier.rs:50:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                             ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
 
-error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
-  --> $DIR/missing-lifetime-specifier.rs:54:45
-   |
-LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
-   |                                             ^^^^^^^^^^^^^^^^^
-
 error[E0107]: wrong number of lifetime arguments: expected 2, found 1
-  --> $DIR/missing-lifetime-specifier.rs:54:45
+  --> $DIR/missing-lifetime-specifier.rs:50:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                             ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
 
-error: aborting due to 28 previous errors
+error: aborting due to 22 previous errors
 
-Some errors have detailed explanations: E0106, E0107, E0228.
+Some errors have detailed explanations: E0106, E0107.
 For more information about an error, try `rustc --explain E0106`.