diff options
Diffstat (limited to 'compiler')
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(); |
