about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs42
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs6
-rw-r--r--compiler/rustc_data_structures/src/fingerprint.rs1
-rw-r--r--compiler/rustc_data_structures/src/flock/windows.rs1
-rw-r--r--compiler/rustc_data_structures/src/graph/implementation/mod.rs1
-rw-r--r--compiler/rustc_data_structures/src/graph/implementation/tests.rs1
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/mod.rs1
-rw-r--r--compiler/rustc_data_structures/src/lib.rs63
-rw-r--r--compiler/rustc_data_structures/src/macros.rs37
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/mod.rs2
-rw-r--r--compiler/rustc_data_structures/src/packed.rs4
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs1
-rw-r--r--compiler/rustc_data_structures/src/stable_hasher.rs2
-rw-r--r--compiler/rustc_data_structures/src/tiny_list.rs80
-rw-r--r--compiler/rustc_data_structures/src/tiny_list/tests.rs155
-rw-r--r--compiler/rustc_data_structures/src/vec_linked_list.rs70
-rw-r--r--compiler/rustc_hir/src/lang_items.rs32
-rw-r--r--compiler/rustc_lint/src/reference_casting.rs3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs17
-rw-r--r--compiler/rustc_passes/messages.ftl10
-rw-r--r--compiler/rustc_passes/src/errors.rs10
-rw-r--r--compiler/rustc_passes/src/loops.rs32
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs120
25 files changed, 210 insertions, 488 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
index da5456692ab..ccd9fb25739 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
@@ -1,4 +1,3 @@
-use rustc_data_structures::vec_linked_list as vll;
 use rustc_index::IndexVec;
 use rustc_middle::mir::visit::{PlaceContext, Visitor};
 use rustc_middle::mir::{Body, Local, Location};
@@ -37,9 +36,12 @@ pub(crate) struct LocalUseMap {
     /// we add for each local variable.
     first_drop_at: IndexVec<Local, Option<AppearanceIndex>>,
 
-    appearances: IndexVec<AppearanceIndex, Appearance>,
+    appearances: Appearances,
 }
 
+// The `Appearance::next` field effectively embeds a linked list within `Appearances`.
+type Appearances = IndexVec<AppearanceIndex, Appearance>;
+
 struct Appearance {
     point_index: PointIndex,
     next: Option<AppearanceIndex>,
@@ -49,14 +51,34 @@ rustc_index::newtype_index! {
     pub struct AppearanceIndex {}
 }
 
-impl vll::LinkElem for Appearance {
-    type LinkIndex = AppearanceIndex;
+fn appearances_iter(
+    first: Option<AppearanceIndex>,
+    appearances: &Appearances,
+) -> impl Iterator<Item = AppearanceIndex> + '_ {
+    AppearancesIter { appearances, current: first }
+}
+
+// Iterates over `Appearances` by following `next` fields.
+struct AppearancesIter<'a> {
+    appearances: &'a Appearances,
+    current: Option<AppearanceIndex>,
+}
 
-    fn next(elem: &Self) -> Option<AppearanceIndex> {
-        elem.next
+impl<'a> Iterator for AppearancesIter<'a> {
+    type Item = AppearanceIndex;
+
+    fn next(&mut self) -> Option<AppearanceIndex> {
+        if let Some(c) = self.current {
+            self.current = self.appearances[c].next;
+            Some(c)
+        } else {
+            None
+        }
     }
 }
 
+//-----------------------------------------------------------------------------
+
 impl LocalUseMap {
     pub(crate) fn build(
         live_locals: &[Local],
@@ -86,17 +108,17 @@ impl LocalUseMap {
     }
 
     pub(crate) fn defs(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
-        vll::iter(self.first_def_at[local], &self.appearances)
+        appearances_iter(self.first_def_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 
     pub(crate) fn uses(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
-        vll::iter(self.first_use_at[local], &self.appearances)
+        appearances_iter(self.first_use_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 
     pub(crate) fn drops(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
-        vll::iter(self.first_drop_at[local], &self.appearances)
+        appearances_iter(self.first_drop_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 }
@@ -146,7 +168,7 @@ impl LocalUseMapBuild<'_> {
     fn insert(
         elements: &DenseLocationMap,
         first_appearance: &mut Option<AppearanceIndex>,
-        appearances: &mut IndexVec<AppearanceIndex, Appearance>,
+        appearances: &mut Appearances,
         location: Location,
     ) {
         let point_index = elements.point_from_location(location);
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index dc73caa4ad5..a6457f4a433 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -31,7 +31,7 @@ pub(crate) fn expand_deriving_partial_eq(
                     };
 
                     // We received arguments of type `&T`. Convert them to type `T` by stripping
-                    // any leading `&` or adding `*`. This isn't necessary for type checking, but
+                    // any leading `&`. This isn't necessary for type checking, but
                     // it results in better error messages if something goes wrong.
                     //
                     // Note: for arguments that look like `&{ x }`, which occur with packed
@@ -53,8 +53,7 @@ pub(crate) fn expand_deriving_partial_eq(
                                 inner.clone()
                             }
                         } else {
-                            // No leading `&`: add a leading `*`.
-                            cx.expr_deref(field.span, expr.clone())
+                            expr.clone()
                         }
                     };
                     cx.expr_binary(
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index d6e2d1d4d07..e3a93ae13e4 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -123,7 +123,7 @@ fn assert_ty_bounds(
     span: Span,
     assert_path: &[Symbol],
 ) {
-    // Deny anonymous structs or unions to avoid wierd errors.
+    // Deny anonymous structs or unions to avoid weird errors.
     assert!(!ty.kind.is_anon_adt(), "Anonymous structs or unions cannot be type parameters");
     // Generate statement `let _: assert_path<ty>;`.
     let span = cx.with_def_site_ctxt(span);
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 2450ac8f4b3..a4d980465e4 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -315,7 +315,7 @@ fn make_format_args(
 
     let mut used = vec![false; args.explicit_args().len()];
     let mut invalid_refs = Vec::new();
-    let mut numeric_refences_to_named_arg = Vec::new();
+    let mut numeric_references_to_named_arg = Vec::new();
 
     enum ArgRef<'a> {
         Index(usize),
@@ -336,7 +336,7 @@ fn make_format_args(
                     used[index] = true;
                     if arg.kind.ident().is_some() {
                         // This was a named argument, but it was used as a positional argument.
-                        numeric_refences_to_named_arg.push((index, span, used_as));
+                        numeric_references_to_named_arg.push((index, span, used_as));
                     }
                     Ok(index)
                 } else {
@@ -544,7 +544,7 @@ fn make_format_args(
     // Only check for unused named argument names if there are no other errors to avoid causing
     // too much noise in output errors, such as when a named argument is entirely unused.
     if invalid_refs.is_empty() && !has_unused && !unnamed_arg_after_named_arg {
-        for &(index, span, used_as) in &numeric_refences_to_named_arg {
+        for &(index, span, used_as) in &numeric_references_to_named_arg {
             let (position_sp_to_replace, position_sp_for_msg) = match used_as {
                 Placeholder(pspan) => (span, pspan),
                 Precision => {
diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs
index 9995c08345c..1bee159489d 100644
--- a/compiler/rustc_data_structures/src/fingerprint.rs
+++ b/compiler/rustc_data_structures/src/fingerprint.rs
@@ -1,3 +1,4 @@
+use crate::stable_hasher::impl_stable_traits_for_trivial_type;
 use crate::stable_hasher::{Hash64, StableHasher, StableHasherResult};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::hash::{Hash, Hasher};
diff --git a/compiler/rustc_data_structures/src/flock/windows.rs b/compiler/rustc_data_structures/src/flock/windows.rs
index 9be1065135a..7dc72661939 100644
--- a/compiler/rustc_data_structures/src/flock/windows.rs
+++ b/compiler/rustc_data_structures/src/flock/windows.rs
@@ -2,6 +2,7 @@ use std::fs::{File, OpenOptions};
 use std::io;
 use std::os::windows::prelude::*;
 use std::path::Path;
+use tracing::debug;
 
 use windows::{
     Win32::Foundation::{ERROR_INVALID_FUNCTION, HANDLE},
diff --git a/compiler/rustc_data_structures/src/graph/implementation/mod.rs b/compiler/rustc_data_structures/src/graph/implementation/mod.rs
index 3910c6fa46d..8cf4b4153db 100644
--- a/compiler/rustc_data_structures/src/graph/implementation/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/implementation/mod.rs
@@ -22,6 +22,7 @@
 
 use rustc_index::bit_set::BitSet;
 use std::fmt::Debug;
+use tracing::debug;
 
 #[cfg(test)]
 mod tests;
diff --git a/compiler/rustc_data_structures/src/graph/implementation/tests.rs b/compiler/rustc_data_structures/src/graph/implementation/tests.rs
index 3ae5f5868f0..b4dbd65db94 100644
--- a/compiler/rustc_data_structures/src/graph/implementation/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/implementation/tests.rs
@@ -1,4 +1,5 @@
 use crate::graph::implementation::*;
+use tracing::debug;
 
 type TestGraph = Graph<&'static str, &'static str>;
 
diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs
index 5021e5e8fc0..914a6a16348 100644
--- a/compiler/rustc_data_structures/src/graph/scc/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs
@@ -10,6 +10,7 @@ use crate::graph::vec_graph::VecGraph;
 use crate::graph::{DirectedGraph, NumEdges, Successors};
 use rustc_index::{Idx, IndexSlice, IndexVec};
 use std::ops::Range;
+use tracing::{debug, instrument};
 
 #[cfg(test)]
 mod tests;
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 8dd85b25e0e..85b5a3cdb7c 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -42,66 +42,59 @@
 #![feature(unwrap_infallible)]
 // tidy-alphabetical-end
 
-#[macro_use]
-extern crate tracing;
-
-use std::fmt;
-
+pub use atomic_ref::AtomicRef;
+pub use ena::snapshot_vec;
+pub use ena::undo_log;
+pub use ena::unify;
 pub use rustc_index::static_assert_size;
 
-/// This calls the passed function while ensuring it won't be inlined into the caller.
-#[inline(never)]
-#[cold]
-pub fn outline<F: FnOnce() -> R, R>(f: F) -> R {
-    f()
-}
+use std::fmt;
 
+pub mod aligned;
 pub mod base_n;
 pub mod binary_search_util;
 pub mod captures;
+pub mod fingerprint;
 pub mod flat_map_in_place;
 pub mod flock;
+pub mod frozen;
 pub mod fx;
 pub mod graph;
 pub mod intern;
 pub mod jobserver;
-pub mod macros;
+pub mod marker;
+pub mod memmap;
 pub mod obligation_forest;
+pub mod owned_slice;
+pub mod packed;
+pub mod profiling;
+pub mod sharded;
 pub mod sip128;
 pub mod small_c_str;
 pub mod snapshot_map;
-pub mod svh;
-pub use ena::snapshot_vec;
-pub mod memmap;
 pub mod sorted_map;
-#[macro_use]
+pub mod sso;
 pub mod stable_hasher;
-mod atomic_ref;
-pub mod fingerprint;
-pub mod marker;
-pub mod profiling;
-pub mod sharded;
 pub mod stack;
-pub mod sync;
-pub mod tiny_list;
-pub mod transitive_relation;
-pub mod vec_linked_list;
-pub mod work_queue;
-pub use atomic_ref::AtomicRef;
-pub mod aligned;
-pub mod frozen;
-mod hashes;
-pub mod owned_slice;
-pub mod packed;
-pub mod sso;
 pub mod steal;
+pub mod svh;
+pub mod sync;
 pub mod tagged_ptr;
 pub mod temp_dir;
+pub mod transitive_relation;
 pub mod unhash;
 pub mod unord;
+pub mod work_queue;
 
-pub use ena::undo_log;
-pub use ena::unify;
+mod atomic_ref;
+mod hashes;
+
+/// This calls the passed function while ensuring it won't be inlined into the caller.
+#[inline(never)]
+#[cold]
+pub fn outline<F: FnOnce() -> R, R>(f: F) -> R {
+    f()
+}
 
 /// Returns a structure that calls `f` when dropped.
 pub fn defer<F: FnOnce()>(f: F) -> OnDrop<F> {
diff --git a/compiler/rustc_data_structures/src/macros.rs b/compiler/rustc_data_structures/src/macros.rs
deleted file mode 100644
index e05491f6ff6..00000000000
--- a/compiler/rustc_data_structures/src/macros.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-#[macro_export]
-macro_rules! enum_from_u32 {
-    ($(#[$attr:meta])* pub enum $name:ident {
-        $($(#[$var_attr:meta])* $variant:ident = $e:expr,)*
-    }) => {
-        $(#[$attr])*
-        pub enum $name {
-            $($(#[$var_attr])* $variant = $e),*
-        }
-
-        impl $name {
-            pub fn from_u32(u: u32) -> Option<$name> {
-                $(if u == $name::$variant as u32 {
-                    return Some($name::$variant)
-                })*
-                None
-            }
-        }
-    };
-    ($(#[$attr:meta])* pub enum $name:ident {
-        $($(#[$var_attr:meta])* $variant:ident,)*
-    }) => {
-        $(#[$attr])*
-        pub enum $name {
-            $($(#[$var_attr])* $variant,)*
-        }
-
-        impl $name {
-            pub fn from_u32(u: u32) -> Option<$name> {
-                $(if u == $name::$variant as u32 {
-                    return Some($name::$variant)
-                })*
-                None
-            }
-        }
-    }
-}
diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index a47908648ba..d477b86da74 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -70,12 +70,12 @@
 //! aren't needed anymore.
 
 use crate::fx::{FxHashMap, FxHashSet};
-
 use std::cell::Cell;
 use std::collections::hash_map::Entry;
 use std::fmt::Debug;
 use std::hash;
 use std::marker::PhantomData;
+use tracing::debug;
 
 mod graphviz;
 
diff --git a/compiler/rustc_data_structures/src/packed.rs b/compiler/rustc_data_structures/src/packed.rs
index b8d4b295dfa..0a392d91988 100644
--- a/compiler/rustc_data_structures/src/packed.rs
+++ b/compiler/rustc_data_structures/src/packed.rs
@@ -3,8 +3,10 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::cmp::Ordering;
 use std::fmt;
 
-#[repr(packed(8))]
+/// A packed 128-bit integer. Useful for reducing the size of structures in
+/// some cases.
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
+#[repr(packed(8))]
 pub struct Pu128(pub u128);
 
 impl Pu128 {
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index 2569684df3f..c6d51a5d6b4 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -99,6 +99,7 @@ pub use measureme::EventId;
 use measureme::{EventIdBuilder, Profiler, SerializableString, StringId};
 use parking_lot::RwLock;
 use smallvec::SmallVec;
+use tracing::warn;
 
 bitflags::bitflags! {
     #[derive(Clone, Copy)]
diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs
index 8418b4bbd47..b5bdf2e1790 100644
--- a/compiler/rustc_data_structures/src/stable_hasher.rs
+++ b/compiler/rustc_data_structures/src/stable_hasher.rs
@@ -296,6 +296,8 @@ macro_rules! impl_stable_traits_for_trivial_type {
     };
 }
 
+pub(crate) use impl_stable_traits_for_trivial_type;
+
 impl_stable_traits_for_trivial_type!(i8);
 impl_stable_traits_for_trivial_type!(i16);
 impl_stable_traits_for_trivial_type!(i32);
diff --git a/compiler/rustc_data_structures/src/tiny_list.rs b/compiler/rustc_data_structures/src/tiny_list.rs
deleted file mode 100644
index 11a408f216a..00000000000
--- a/compiler/rustc_data_structures/src/tiny_list.rs
+++ /dev/null
@@ -1,80 +0,0 @@
-//! A singly-linked list.
-//!
-//! Using this data structure only makes sense under very specific
-//! circumstances:
-//!
-//! - If you have a list that rarely stores more than one element, then this
-//!   data-structure can store the element without allocating and only uses as
-//!   much space as an `Option<(T, usize)>`. If T can double as the `Option`
-//!   discriminant, it will even only be as large as `T, usize`.
-//!
-//! If you expect to store more than 1 element in the common case, steer clear
-//! and use a `Vec<T>`, `Box<[T]>`, or a `SmallVec<T>`.
-
-#[cfg(test)]
-mod tests;
-
-#[derive(Clone)]
-pub struct TinyList<T> {
-    head: Option<Element<T>>,
-}
-
-impl<T: PartialEq> TinyList<T> {
-    #[inline]
-    pub fn new() -> TinyList<T> {
-        TinyList { head: None }
-    }
-
-    #[inline]
-    pub fn new_single(data: T) -> TinyList<T> {
-        TinyList { head: Some(Element { data, next: None }) }
-    }
-
-    #[inline]
-    pub fn insert(&mut self, data: T) {
-        self.head = Some(Element { data, next: self.head.take().map(Box::new) });
-    }
-
-    #[inline]
-    pub fn remove(&mut self, data: &T) -> bool {
-        self.head = match &mut self.head {
-            Some(head) if head.data == *data => head.next.take().map(|x| *x),
-            Some(head) => return head.remove_next(data),
-            None => return false,
-        };
-        true
-    }
-
-    #[inline]
-    pub fn contains(&self, data: &T) -> bool {
-        let mut elem = self.head.as_ref();
-        while let Some(e) = elem {
-            if &e.data == data {
-                return true;
-            }
-            elem = e.next.as_deref();
-        }
-        false
-    }
-}
-
-#[derive(Clone)]
-struct Element<T> {
-    data: T,
-    next: Option<Box<Element<T>>>,
-}
-
-impl<T: PartialEq> Element<T> {
-    fn remove_next(mut self: &mut Self, data: &T) -> bool {
-        loop {
-            match self.next {
-                Some(ref mut next) if next.data == *data => {
-                    self.next = next.next.take();
-                    return true;
-                }
-                Some(ref mut next) => self = next,
-                None => return false,
-            }
-        }
-    }
-}
diff --git a/compiler/rustc_data_structures/src/tiny_list/tests.rs b/compiler/rustc_data_structures/src/tiny_list/tests.rs
deleted file mode 100644
index 4b95e62bef0..00000000000
--- a/compiler/rustc_data_structures/src/tiny_list/tests.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-use super::*;
-
-extern crate test;
-use test::{black_box, Bencher};
-
-impl<T> TinyList<T> {
-    fn len(&self) -> usize {
-        let (mut elem, mut count) = (self.head.as_ref(), 0);
-        while let Some(e) = elem {
-            count += 1;
-            elem = e.next.as_deref();
-        }
-        count
-    }
-}
-
-#[test]
-fn test_contains_and_insert() {
-    fn do_insert(i: u32) -> bool {
-        i % 2 == 0
-    }
-
-    let mut list = TinyList::new();
-
-    for i in 0..10 {
-        for j in 0..i {
-            if do_insert(j) {
-                assert!(list.contains(&j));
-            } else {
-                assert!(!list.contains(&j));
-            }
-        }
-
-        assert!(!list.contains(&i));
-
-        if do_insert(i) {
-            list.insert(i);
-            assert!(list.contains(&i));
-        }
-    }
-}
-
-#[test]
-fn test_remove_first() {
-    let mut list = TinyList::new();
-    list.insert(1);
-    list.insert(2);
-    list.insert(3);
-    list.insert(4);
-    assert_eq!(list.len(), 4);
-
-    assert!(list.remove(&4));
-    assert!(!list.contains(&4));
-
-    assert_eq!(list.len(), 3);
-    assert!(list.contains(&1));
-    assert!(list.contains(&2));
-    assert!(list.contains(&3));
-}
-
-#[test]
-fn test_remove_last() {
-    let mut list = TinyList::new();
-    list.insert(1);
-    list.insert(2);
-    list.insert(3);
-    list.insert(4);
-    assert_eq!(list.len(), 4);
-
-    assert!(list.remove(&1));
-    assert!(!list.contains(&1));
-
-    assert_eq!(list.len(), 3);
-    assert!(list.contains(&2));
-    assert!(list.contains(&3));
-    assert!(list.contains(&4));
-}
-
-#[test]
-fn test_remove_middle() {
-    let mut list = TinyList::new();
-    list.insert(1);
-    list.insert(2);
-    list.insert(3);
-    list.insert(4);
-    assert_eq!(list.len(), 4);
-
-    assert!(list.remove(&2));
-    assert!(!list.contains(&2));
-
-    assert_eq!(list.len(), 3);
-    assert!(list.contains(&1));
-    assert!(list.contains(&3));
-    assert!(list.contains(&4));
-}
-
-#[test]
-fn test_remove_single() {
-    let mut list = TinyList::new();
-    list.insert(1);
-    assert_eq!(list.len(), 1);
-
-    assert!(list.remove(&1));
-    assert!(!list.contains(&1));
-
-    assert_eq!(list.len(), 0);
-}
-
-#[bench]
-fn bench_insert_empty(b: &mut Bencher) {
-    b.iter(|| {
-        let mut list = black_box(TinyList::new());
-        list.insert(1);
-        list
-    })
-}
-
-#[bench]
-fn bench_insert_one(b: &mut Bencher) {
-    b.iter(|| {
-        let mut list = black_box(TinyList::new_single(0));
-        list.insert(1);
-        list
-    })
-}
-
-#[bench]
-fn bench_contains_empty(b: &mut Bencher) {
-    b.iter(|| black_box(TinyList::new()).contains(&1));
-}
-
-#[bench]
-fn bench_contains_unknown(b: &mut Bencher) {
-    b.iter(|| black_box(TinyList::new_single(0)).contains(&1));
-}
-
-#[bench]
-fn bench_contains_one(b: &mut Bencher) {
-    b.iter(|| black_box(TinyList::new_single(1)).contains(&1));
-}
-
-#[bench]
-fn bench_remove_empty(b: &mut Bencher) {
-    b.iter(|| black_box(TinyList::new()).remove(&1));
-}
-
-#[bench]
-fn bench_remove_unknown(b: &mut Bencher) {
-    b.iter(|| black_box(TinyList::new_single(0)).remove(&1));
-}
-
-#[bench]
-fn bench_remove_one(b: &mut Bencher) {
-    b.iter(|| black_box(TinyList::new_single(1)).remove(&1));
-}
diff --git a/compiler/rustc_data_structures/src/vec_linked_list.rs b/compiler/rustc_data_structures/src/vec_linked_list.rs
deleted file mode 100644
index fda72c9a3b2..00000000000
--- a/compiler/rustc_data_structures/src/vec_linked_list.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-use rustc_index::{Idx, IndexVec};
-
-pub fn iter<Ls>(
-    first: Option<Ls::LinkIndex>,
-    links: &Ls,
-) -> impl Iterator<Item = Ls::LinkIndex> + '_
-where
-    Ls: Links,
-{
-    VecLinkedListIterator { links, current: first }
-}
-
-pub struct VecLinkedListIterator<Ls>
-where
-    Ls: Links,
-{
-    links: Ls,
-    current: Option<Ls::LinkIndex>,
-}
-
-impl<Ls> Iterator for VecLinkedListIterator<Ls>
-where
-    Ls: Links,
-{
-    type Item = Ls::LinkIndex;
-
-    fn next(&mut self) -> Option<Ls::LinkIndex> {
-        if let Some(c) = self.current {
-            self.current = <Ls as Links>::next(&self.links, c);
-            Some(c)
-        } else {
-            None
-        }
-    }
-}
-
-pub trait Links {
-    type LinkIndex: Copy;
-
-    fn next(links: &Self, index: Self::LinkIndex) -> Option<Self::LinkIndex>;
-}
-
-impl<Ls> Links for &Ls
-where
-    Ls: Links,
-{
-    type LinkIndex = Ls::LinkIndex;
-
-    fn next(links: &Self, index: Ls::LinkIndex) -> Option<Ls::LinkIndex> {
-        <Ls as Links>::next(links, index)
-    }
-}
-
-pub trait LinkElem {
-    type LinkIndex: Copy;
-
-    fn next(elem: &Self) -> Option<Self::LinkIndex>;
-}
-
-impl<L, E> Links for IndexVec<L, E>
-where
-    E: LinkElem<LinkIndex = L>,
-    L: Idx,
-{
-    type LinkIndex = L;
-
-    fn next(links: &Self, index: L) -> Option<L> {
-        <E as LinkElem>::next(&links[index])
-    }
-}
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index e870a04127a..c4be67cdd88 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -55,21 +55,27 @@ macro_rules! language_item_table {
     (
         $( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )*
     ) => {
-
-        rustc_data_structures::enum_from_u32! {
-            /// A representation of all the valid lang items in Rust.
-            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
-            pub enum LangItem {
-                $(
-                    #[doc = concat!("The `", stringify!($name), "` lang item.")]
-                    ///
-                    $(#[$attr])*
-                    $variant,
-                )*
-            }
+        /// A representation of all the valid lang items in Rust.
+        #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
+        pub enum LangItem {
+            $(
+                #[doc = concat!("The `", stringify!($name), "` lang item.")]
+                $(#[$attr])*
+                $variant,
+            )*
         }
 
         impl LangItem {
+            fn from_u32(u: u32) -> Option<LangItem> {
+                // This implementation is clumsy, but makes no assumptions
+                // about how discriminant tags are allocated within the
+                // range `0 .. std::mem::variant_count::<LangItem>()`.
+                $(if u == LangItem::$variant as u32 {
+                    return Some(LangItem::$variant)
+                })*
+                None
+            }
+
             /// Returns the `name` symbol in `#[lang = "$name"]`.
             /// For example, [`LangItem::PartialEq`]`.name()`
             /// would result in [`sym::eq`] since it is `#[lang = "eq"]`.
@@ -147,7 +153,7 @@ language_item_table! {
     Clone,                   sym::clone,               clone_trait,                Target::Trait,          GenericRequirement::None;
     Sync,                    sym::sync,                sync_trait,                 Target::Trait,          GenericRequirement::Exact(0);
     DiscriminantKind,        sym::discriminant_kind,   discriminant_kind_trait,    Target::Trait,          GenericRequirement::None;
-    /// The associated item of the [`DiscriminantKind`] trait.
+    /// The associated item of the `DiscriminantKind` trait.
     Discriminant,            sym::discriminant_type,   discriminant_type,          Target::AssocTy,        GenericRequirement::None;
 
     PointeeTrait,            sym::pointee_trait,       pointee_trait,              Target::Trait,          GenericRequirement::None;
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index 63d55a73a98..b80e90c25a3 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -202,7 +202,8 @@ fn is_cast_to_bigger_memory_layout<'tcx>(
 
     // if the current expr looks like this `&mut expr[index]` then just looking
     // at `expr[index]` won't give us the underlying allocation, so we just skip it
-    if let ExprKind::Index(..) = e_alloc.kind {
+    // the same logic applies field access like `&mut expr.field`
+    if let ExprKind::Index(..) | ExprKind::Field(..) = e_alloc.kind {
         return None;
     }
 
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index ee3cdf36820..38cb1d5f9a0 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -125,10 +125,11 @@ use std::io::{Read, Write};
 use std::num::NonZero;
 use std::sync::atomic::{AtomicU32, Ordering};
 
+use smallvec::{smallvec, SmallVec};
+
 use rustc_ast::LitKind;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{HashMapExt, Lock};
-use rustc_data_structures::tiny_list::TinyList;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
@@ -266,8 +267,8 @@ type DecodingSessionId = NonZero<u32>;
 #[derive(Clone)]
 enum State {
     Empty,
-    InProgressNonAlloc(TinyList<DecodingSessionId>),
-    InProgress(TinyList<DecodingSessionId>, AllocId),
+    InProgressNonAlloc(SmallVec<[DecodingSessionId; 1]>),
+    InProgress(SmallVec<[DecodingSessionId; 1]>, AllocId),
     Done(AllocId),
 }
 
@@ -337,8 +338,7 @@ impl<'s> AllocDecodingSession<'s> {
                             // If this is an allocation, we need to reserve an
                             // `AllocId` so we can decode cyclic graphs.
                             let alloc_id = decoder.interner().reserve_alloc_id();
-                            *entry =
-                                State::InProgress(TinyList::new_single(self.session_id), alloc_id);
+                            *entry = State::InProgress(smallvec![self.session_id], alloc_id);
                             Some(alloc_id)
                         }
                         AllocDiscriminant::Fn
@@ -346,8 +346,7 @@ impl<'s> AllocDecodingSession<'s> {
                         | AllocDiscriminant::VTable => {
                             // Fns and statics cannot be cyclic, and their `AllocId`
                             // is determined later by interning.
-                            *entry =
-                                State::InProgressNonAlloc(TinyList::new_single(self.session_id));
+                            *entry = State::InProgressNonAlloc(smallvec![self.session_id]);
                             None
                         }
                     }
@@ -357,7 +356,7 @@ impl<'s> AllocDecodingSession<'s> {
                         bug!("this should be unreachable");
                     } else {
                         // Start decoding concurrently.
-                        sessions.insert(self.session_id);
+                        sessions.push(self.session_id);
                         None
                     }
                 }
@@ -367,7 +366,7 @@ impl<'s> AllocDecodingSession<'s> {
                         return alloc_id;
                     } else {
                         // Start decoding concurrently.
-                        sessions.insert(self.session_id);
+                        sessions.push(self.session_id);
                         Some(alloc_id)
                     }
                 }
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 9d58d301e2b..3deefcaa06c 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -52,16 +52,16 @@ passes_attr_only_in_functions =
 passes_both_ffi_const_and_pure =
     `#[ffi_const]` function cannot be `#[ffi_pure]`
 
-passes_break_inside_async_block =
-    `{$name}` inside of an `async` block
-    .label = cannot `{$name}` inside of an `async` block
-    .async_block_label = enclosing `async` block
-
 passes_break_inside_closure =
     `{$name}` inside of a closure
     .label = cannot `{$name}` inside of a closure
     .closure_label = enclosing closure
 
+passes_break_inside_coroutine =
+    `{$name}` inside `{$kind}` {$source}
+    .label = cannot `{$name}` inside `{$kind}` {$source}
+    .coroutine_label = enclosing `{$kind}` {$source}
+
 passes_break_non_loop =
     `break` with value from a `{$kind}` loop
     .label = can only break with a value inside `loop` or breakable block
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 65cad82cc8c..b8586e7e974 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1086,14 +1086,16 @@ pub struct BreakInsideClosure<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_break_inside_async_block, code = E0267)]
-pub struct BreakInsideAsyncBlock<'a> {
+#[diag(passes_break_inside_coroutine, code = E0267)]
+pub struct BreakInsideCoroutine<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(passes_async_block_label)]
-    pub closure_span: Span,
+    #[label(passes_coroutine_label)]
+    pub coroutine_span: Span,
     pub name: &'a str,
+    pub kind: &'a str,
+    pub source: &'a str,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index 4b5c4dfe991..3b20112eab7 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -13,7 +13,7 @@ use rustc_span::hygiene::DesugaringKind;
 use rustc_span::{BytePos, Span};
 
 use crate::errors::{
-    BreakInsideAsyncBlock, BreakInsideClosure, BreakNonLoop, ContinueLabeledBlock, OutsideLoop,
+    BreakInsideClosure, BreakInsideCoroutine, BreakNonLoop, ContinueLabeledBlock, OutsideLoop,
     OutsideLoopSuggestion, UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock,
 };
 
@@ -23,7 +23,7 @@ enum Context {
     Fn,
     Loop(hir::LoopSource),
     Closure(Span),
-    AsyncClosure(Span),
+    Coroutine { coroutine_span: Span, kind: hir::CoroutineDesugaring, source: hir::CoroutineSource },
     UnlabeledBlock(Span),
     LabeledBlock,
     Constant,
@@ -89,12 +89,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
             hir::ExprKind::Closure(&hir::Closure {
                 ref fn_decl, body, fn_decl_span, kind, ..
             }) => {
-                // FIXME(coroutines): This doesn't handle coroutines correctly
                 let cx = match kind {
-                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
-                        hir::CoroutineDesugaring::Async,
-                        hir::CoroutineSource::Block,
-                    )) => AsyncClosure(fn_decl_span),
+                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(kind, source)) => {
+                        Coroutine { coroutine_span: fn_decl_span, kind, source }
+                    }
                     _ => Closure(fn_decl_span),
                 };
                 self.visit_fn_decl(fn_decl);
@@ -227,8 +225,24 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
             Closure(closure_span) => {
                 self.sess.dcx().emit_err(BreakInsideClosure { span, closure_span, name });
             }
-            AsyncClosure(closure_span) => {
-                self.sess.dcx().emit_err(BreakInsideAsyncBlock { span, closure_span, name });
+            Coroutine { coroutine_span, kind, source } => {
+                let kind = match kind {
+                    hir::CoroutineDesugaring::Async => "async",
+                    hir::CoroutineDesugaring::Gen => "gen",
+                    hir::CoroutineDesugaring::AsyncGen => "async gen",
+                };
+                let source = match source {
+                    hir::CoroutineSource::Block => "block",
+                    hir::CoroutineSource::Closure => "closure",
+                    hir::CoroutineSource::Fn => "function",
+                };
+                self.sess.dcx().emit_err(BreakInsideCoroutine {
+                    span,
+                    coroutine_span,
+                    name,
+                    kind,
+                    source,
+                });
             }
             UnlabeledBlock(block_span) if is_break && block_span.eq_ctxt(break_span) => {
                 let suggestion = Some(OutsideLoopSuggestion { block_span, break_span });
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index f1eb5b7e826..4b49e014c0f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -350,12 +350,14 @@ impl IgnoredDiagnosticOption {
         option_name: &'static str,
     ) {
         if let (Some(new_item), Some(old_item)) = (new, old) {
-            tcx.emit_node_span_lint(
-                UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
-                new_item,
-                IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
-            );
+            if let Some(item_def_id) = item_def_id.as_local() {
+                tcx.emit_node_span_lint(
+                    UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
+                    tcx.local_def_id_to_hir_id(item_def_id),
+                    new_item,
+                    IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
+                );
+            }
         }
     }
 }
@@ -639,30 +641,38 @@ impl<'tcx> OnUnimplementedDirective {
                     AttrArgs::Eq(span, AttrArgsEq::Hir(expr)) => span.to(expr.span),
                 };
 
-                tcx.emit_node_span_lint(
-                    UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                    tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
-                    report_span,
-                    MalformedOnUnimplementedAttrLint::new(report_span),
-                );
+                if let Some(item_def_id) = item_def_id.as_local() {
+                    tcx.emit_node_span_lint(
+                        UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
+                        tcx.local_def_id_to_hir_id(item_def_id),
+                        report_span,
+                        MalformedOnUnimplementedAttrLint::new(report_span),
+                    );
+                }
                 Ok(None)
             }
         } else if is_diagnostic_namespace_variant {
             match &attr.kind {
                 AttrKind::Normal(p) if !matches!(p.item.args, AttrArgs::Empty) => {
-                    tcx.emit_node_span_lint(
-                        UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                        tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
-                        attr.span,
-                        MalformedOnUnimplementedAttrLint::new(attr.span),
-                    );
+                    if let Some(item_def_id) = item_def_id.as_local() {
+                        tcx.emit_node_span_lint(
+                            UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
+                            tcx.local_def_id_to_hir_id(item_def_id),
+                            attr.span,
+                            MalformedOnUnimplementedAttrLint::new(attr.span),
+                        );
+                    }
+                }
+                _ => {
+                    if let Some(item_def_id) = item_def_id.as_local() {
+                        tcx.emit_node_span_lint(
+                            UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
+                            tcx.local_def_id_to_hir_id(item_def_id),
+                            attr.span,
+                            MissingOptionsForOnUnimplementedAttr,
+                        )
+                    }
                 }
-                _ => tcx.emit_node_span_lint(
-                    UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                    tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
-                    attr.span,
-                    MissingOptionsForOnUnimplementedAttr,
-                ),
             };
 
             Ok(None)
@@ -791,12 +801,14 @@ impl<'tcx> OnUnimplementedFormatString {
                             || format_spec.precision_span.is_some()
                             || format_spec.fill_span.is_some())
                     {
-                        tcx.emit_node_span_lint(
-                            UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                            tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
-                            self.span,
-                            InvalidFormatSpecifier,
-                        );
+                        if let Some(item_def_id) = item_def_id.as_local() {
+                            tcx.emit_node_span_lint(
+                                UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
+                                tcx.local_def_id_to_hir_id(item_def_id),
+                                self.span,
+                                InvalidFormatSpecifier,
+                            );
+                        }
                     }
                     match a.position {
                         Position::ArgumentNamed(s) => {
@@ -812,15 +824,17 @@ impl<'tcx> OnUnimplementedFormatString {
                                 s if generics.params.iter().any(|param| param.name == s) => (),
                                 s => {
                                     if self.is_diagnostic_namespace_variant {
-                                        tcx.emit_node_span_lint(
-                                            UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                                            tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
-                                            self.span,
-                                            UnknownFormatParameterForOnUnimplementedAttr {
-                                                argument_name: s,
-                                                trait_name,
-                                            },
-                                        );
+                                        if let Some(item_def_id) = item_def_id.as_local() {
+                                            tcx.emit_node_span_lint(
+                                                UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
+                                                tcx.local_def_id_to_hir_id(item_def_id),
+                                                self.span,
+                                                UnknownFormatParameterForOnUnimplementedAttr {
+                                                    argument_name: s,
+                                                    trait_name,
+                                                },
+                                            );
+                                        }
                                     } else {
                                         result = Err(struct_span_code_err!(
                                             tcx.dcx(),
@@ -842,12 +856,14 @@ impl<'tcx> OnUnimplementedFormatString {
                         // `{:1}` and `{}` are not to be used
                         Position::ArgumentIs(..) | Position::ArgumentImplicitlyIs(_) => {
                             if self.is_diagnostic_namespace_variant {
-                                tcx.emit_node_span_lint(
-                                    UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                                    tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
-                                    self.span,
-                                    DisallowedPositionalArgument,
-                                );
+                                if let Some(item_def_id) = item_def_id.as_local() {
+                                    tcx.emit_node_span_lint(
+                                        UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
+                                        tcx.local_def_id_to_hir_id(item_def_id),
+                                        self.span,
+                                        DisallowedPositionalArgument,
+                                    );
+                                }
                             } else {
                                 let reported = struct_span_code_err!(
                                     tcx.dcx(),
@@ -870,12 +886,14 @@ impl<'tcx> OnUnimplementedFormatString {
         // so that users are aware that something is not correct
         for e in parser.errors {
             if self.is_diagnostic_namespace_variant {
-                tcx.emit_node_span_lint(
-                    UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                    tcx.local_def_id_to_hir_id(item_def_id.expect_local()),
-                    self.span,
-                    WrappedParserError { description: e.description, label: e.label },
-                );
+                if let Some(item_def_id) = item_def_id.as_local() {
+                    tcx.emit_node_span_lint(
+                        UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
+                        tcx.local_def_id_to_hir_id(item_def_id),
+                        self.span,
+                        WrappedParserError { description: e.description, label: e.label },
+                    );
+                }
             } else {
                 let reported =
                     struct_span_code_err!(tcx.dcx(), self.span, E0231, "{}", e.description,).emit();