diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 219517b4ab2e2..7517ab66170a2 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -369,7 +369,7 @@ struct DiagnosticMetadata<'ast> { /// param. currently_processing_generics: bool, - /// The current enclosing function (used for better errors). + /// The current enclosing (non-closure) function (used for better errors). current_function: Option<(FnKind<'ast>, Span)>, /// A list of labels as of yet unused. Labels will be removed from this map when @@ -515,8 +515,10 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { FnKind::Fn(FnCtxt::Assoc(_), ..) => NormalRibKind, FnKind::Closure(..) => ClosureOrAsyncRibKind, }; - let previous_value = - replace(&mut self.diagnostic_metadata.current_function, Some((fn_kind, sp))); + let previous_value = self.diagnostic_metadata.current_function; + if matches!(fn_kind, FnKind::Fn(..)) { + self.diagnostic_metadata.current_function = Some((fn_kind, sp)); + } debug!("(resolving function) entering function"); let declaration = fn_kind.decl(); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6677a5ffe2867..e7486db4debcc 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1240,9 +1240,6 @@ impl<'a> Resolver<'a> { extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default()); if !session.contains_name(&krate.attrs, sym::no_std) { extern_prelude.insert(Ident::with_dummy_span(sym::std), Default::default()); - if session.rust_2018() { - extern_prelude.insert(Ident::with_dummy_span(sym::meta), Default::default()); - } } } diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs index 917fc5631c4f5..b2009962aba2e 100644 --- a/compiler/rustc_typeck/src/coherence/orphan.rs +++ b/compiler/rustc_typeck/src/coherence/orphan.rs @@ -110,7 +110,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> { ) .note( "implementing a foreign trait is only possible if at \ - least one of the types for which is it implemented is local, \ + least one of the types for which it is implemented is local, \ and no uncovered type parameters appear before that first \ local type", ) @@ -135,7 +135,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> { local type", param_ty, )).note("implementing a foreign trait is only possible if at \ - least one of the types for which is it implemented is local" + least one of the types for which it is implemented is local" ).note("only traits defined in the current crate can be \ implemented for a type parameter" ).emit(); diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 606bf94f99867..92cbce96054b8 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -9,13 +9,16 @@ use core::ops::{Index, RangeBounds}; use core::ptr; use super::borrow::DormantMutRef; -use super::node::{self, marker, ForceResult::*, Handle, InsertResult::*, NodeRef}; +use super::node::{self, marker, ForceResult::*, Handle, NodeRef}; use super::search::{self, SearchResult::*}; use super::unwrap_unchecked; -use Entry::*; use UnderflowResult::*; +mod entry; +pub use entry::{Entry, OccupiedEntry, VacantEntry}; +use Entry::*; + /// A map based on a B-Tree. /// /// B-Trees represent a fundamental compromise between cache-efficiency and actually minimizing @@ -452,69 +455,6 @@ impl fmt::Debug for RangeMut<'_, K, V> { } } -/// A view into a single entry in a map, which may either be vacant or occupied. -/// -/// This `enum` is constructed from the [`entry`] method on [`BTreeMap`]. -/// -/// [`entry`]: BTreeMap::entry -#[stable(feature = "rust1", since = "1.0.0")] -pub enum Entry<'a, K: 'a, V: 'a> { - /// A vacant entry. - #[stable(feature = "rust1", since = "1.0.0")] - Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>), - - /// An occupied entry. - #[stable(feature = "rust1", since = "1.0.0")] - Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>), -} - -#[stable(feature = "debug_btree_map", since = "1.12.0")] -impl Debug for Entry<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), - Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(), - } - } -} - -/// A view into a vacant entry in a `BTreeMap`. -/// It is part of the [`Entry`] enum. -#[stable(feature = "rust1", since = "1.0.0")] -pub struct VacantEntry<'a, K: 'a, V: 'a> { - key: K, - handle: Handle, K, V, marker::Leaf>, marker::Edge>, - dormant_map: DormantMutRef<'a, BTreeMap>, - - // Be invariant in `K` and `V` - _marker: PhantomData<&'a mut (K, V)>, -} - -#[stable(feature = "debug_btree_map", since = "1.12.0")] -impl Debug for VacantEntry<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("VacantEntry").field(self.key()).finish() - } -} - -/// A view into an occupied entry in a `BTreeMap`. -/// It is part of the [`Entry`] enum. -#[stable(feature = "rust1", since = "1.0.0")] -pub struct OccupiedEntry<'a, K: 'a, V: 'a> { - handle: Handle, K, V, marker::LeafOrInternal>, marker::KV>, - dormant_map: DormantMutRef<'a, BTreeMap>, - - // Be invariant in `K` and `V` - _marker: PhantomData<&'a mut (K, V)>, -} - -#[stable(feature = "debug_btree_map", since = "1.12.0")] -impl Debug for OccupiedEntry<'_, K, V> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish() - } -} - // An iterator for merging two sorted sequences into one struct MergeIter> { left: Peekable, @@ -2310,409 +2250,6 @@ impl BTreeMap { } } -impl<'a, K: Ord, V> Entry<'a, K, V> { - /// Ensures a value is in the entry by inserting the default if empty, and returns - /// a mutable reference to the value in the entry. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// map.entry("poneyland").or_insert(12); - /// - /// assert_eq!(map["poneyland"], 12); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn or_insert(self, default: V) -> &'a mut V { - match self { - Occupied(entry) => entry.into_mut(), - Vacant(entry) => entry.insert(default), - } - } - - /// Ensures a value is in the entry by inserting the result of the default function if empty, - /// and returns a mutable reference to the value in the entry. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// - /// let mut map: BTreeMap<&str, String> = BTreeMap::new(); - /// let s = "hoho".to_string(); - /// - /// map.entry("poneyland").or_insert_with(|| s); - /// - /// assert_eq!(map["poneyland"], "hoho".to_string()); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn or_insert_with V>(self, default: F) -> &'a mut V { - match self { - Occupied(entry) => entry.into_mut(), - Vacant(entry) => entry.insert(default()), - } - } - - #[unstable(feature = "or_insert_with_key", issue = "71024")] - /// Ensures a value is in the entry by inserting, if empty, the result of the default function, - /// which takes the key as its argument, and returns a mutable reference to the value in the - /// entry. - /// - /// # Examples - /// - /// ``` - /// #![feature(or_insert_with_key)] - /// use std::collections::BTreeMap; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// - /// map.entry("poneyland").or_insert_with_key(|key| key.chars().count()); - /// - /// assert_eq!(map["poneyland"], 9); - /// ``` - #[inline] - pub fn or_insert_with_key V>(self, default: F) -> &'a mut V { - match self { - Occupied(entry) => entry.into_mut(), - Vacant(entry) => { - let value = default(entry.key()); - entry.insert(value) - } - } - } - - /// Returns a reference to this entry's key. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); - /// ``` - #[stable(feature = "map_entry_keys", since = "1.10.0")] - pub fn key(&self) -> &K { - match *self { - Occupied(ref entry) => entry.key(), - Vacant(ref entry) => entry.key(), - } - } - - /// Provides in-place mutable access to an occupied entry before any - /// potential inserts into the map. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// - /// map.entry("poneyland") - /// .and_modify(|e| { *e += 1 }) - /// .or_insert(42); - /// assert_eq!(map["poneyland"], 42); - /// - /// map.entry("poneyland") - /// .and_modify(|e| { *e += 1 }) - /// .or_insert(42); - /// assert_eq!(map["poneyland"], 43); - /// ``` - #[stable(feature = "entry_and_modify", since = "1.26.0")] - pub fn and_modify(self, f: F) -> Self - where - F: FnOnce(&mut V), - { - match self { - Occupied(mut entry) => { - f(entry.get_mut()); - Occupied(entry) - } - Vacant(entry) => Vacant(entry), - } - } -} - -impl<'a, K: Ord, V: Default> Entry<'a, K, V> { - #[stable(feature = "entry_or_default", since = "1.28.0")] - /// Ensures a value is in the entry by inserting the default value if empty, - /// and returns a mutable reference to the value in the entry. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// - /// let mut map: BTreeMap<&str, Option> = BTreeMap::new(); - /// map.entry("poneyland").or_default(); - /// - /// assert_eq!(map["poneyland"], None); - /// ``` - pub fn or_default(self) -> &'a mut V { - match self { - Occupied(entry) => entry.into_mut(), - Vacant(entry) => entry.insert(Default::default()), - } - } -} - -impl<'a, K: Ord, V> VacantEntry<'a, K, V> { - /// Gets a reference to the key that would be used when inserting a value - /// through the VacantEntry. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); - /// ``` - #[stable(feature = "map_entry_keys", since = "1.10.0")] - pub fn key(&self) -> &K { - &self.key - } - - /// Take ownership of the key. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// use std::collections::btree_map::Entry; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// - /// if let Entry::Vacant(v) = map.entry("poneyland") { - /// v.into_key(); - /// } - /// ``` - #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")] - pub fn into_key(self) -> K { - self.key - } - - /// Sets the value of the entry with the `VacantEntry`'s key, - /// and returns a mutable reference to it. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// use std::collections::btree_map::Entry; - /// - /// let mut map: BTreeMap<&str, u32> = BTreeMap::new(); - /// - /// if let Entry::Vacant(o) = map.entry("poneyland") { - /// o.insert(37); - /// } - /// assert_eq!(map["poneyland"], 37); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn insert(self, value: V) -> &'a mut V { - let out_ptr = match self.handle.insert_recursing(self.key, value) { - (Fit(_), val_ptr) => { - // Safety: We have consumed self.handle and the handle returned. - let map = unsafe { self.dormant_map.awaken() }; - map.length += 1; - val_ptr - } - (Split(ins), val_ptr) => { - drop(ins.left); - // Safety: We have consumed self.handle and the reference returned. - let map = unsafe { self.dormant_map.awaken() }; - let root = map.root.as_mut().unwrap(); - root.push_internal_level().push(ins.k, ins.v, ins.right); - map.length += 1; - val_ptr - } - }; - // Now that we have finished growing the tree using borrowed references, - // dereference the pointer to a part of it, that we picked up along the way. - unsafe { &mut *out_ptr } - } -} - -impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { - /// Gets a reference to the key in the entry. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// map.entry("poneyland").or_insert(12); - /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); - /// ``` - #[stable(feature = "map_entry_keys", since = "1.10.0")] - pub fn key(&self) -> &K { - self.handle.reborrow().into_kv().0 - } - - /// Take ownership of the key and value from the map. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// use std::collections::btree_map::Entry; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// map.entry("poneyland").or_insert(12); - /// - /// if let Entry::Occupied(o) = map.entry("poneyland") { - /// // We delete the entry from the map. - /// o.remove_entry(); - /// } - /// - /// // If now try to get the value, it will panic: - /// // println!("{}", map["poneyland"]); - /// ``` - #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")] - pub fn remove_entry(self) -> (K, V) { - self.remove_kv() - } - - /// Gets a reference to the value in the entry. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// use std::collections::btree_map::Entry; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// map.entry("poneyland").or_insert(12); - /// - /// if let Entry::Occupied(o) = map.entry("poneyland") { - /// assert_eq!(o.get(), &12); - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn get(&self) -> &V { - self.handle.reborrow().into_kv().1 - } - - /// Gets a mutable reference to the value in the entry. - /// - /// If you need a reference to the `OccupiedEntry` that may outlive the - /// destruction of the `Entry` value, see [`into_mut`]. - /// - /// [`into_mut`]: OccupiedEntry::into_mut - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// use std::collections::btree_map::Entry; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// map.entry("poneyland").or_insert(12); - /// - /// assert_eq!(map["poneyland"], 12); - /// if let Entry::Occupied(mut o) = map.entry("poneyland") { - /// *o.get_mut() += 10; - /// assert_eq!(*o.get(), 22); - /// - /// // We can use the same Entry multiple times. - /// *o.get_mut() += 2; - /// } - /// assert_eq!(map["poneyland"], 24); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn get_mut(&mut self) -> &mut V { - self.handle.kv_mut().1 - } - - /// Converts the entry into a mutable reference to its value. - /// - /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`]. - /// - /// [`get_mut`]: OccupiedEntry::get_mut - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// use std::collections::btree_map::Entry; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// map.entry("poneyland").or_insert(12); - /// - /// assert_eq!(map["poneyland"], 12); - /// if let Entry::Occupied(o) = map.entry("poneyland") { - /// *o.into_mut() += 10; - /// } - /// assert_eq!(map["poneyland"], 22); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn into_mut(self) -> &'a mut V { - self.handle.into_val_mut() - } - - /// Sets the value of the entry with the `OccupiedEntry`'s key, - /// and returns the entry's old value. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// use std::collections::btree_map::Entry; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// map.entry("poneyland").or_insert(12); - /// - /// if let Entry::Occupied(mut o) = map.entry("poneyland") { - /// assert_eq!(o.insert(15), 12); - /// } - /// assert_eq!(map["poneyland"], 15); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn insert(&mut self, value: V) -> V { - mem::replace(self.get_mut(), value) - } - - /// Takes the value of the entry out of the map, and returns it. - /// - /// # Examples - /// - /// ``` - /// use std::collections::BTreeMap; - /// use std::collections::btree_map::Entry; - /// - /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); - /// map.entry("poneyland").or_insert(12); - /// - /// if let Entry::Occupied(o) = map.entry("poneyland") { - /// assert_eq!(o.remove(), 12); - /// } - /// // If we try to get "poneyland"'s value, it'll panic: - /// // println!("{}", map["poneyland"]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn remove(self) -> V { - self.remove_kv().1 - } - - // Body of `remove_entry`, separate to keep the above implementations short. - fn remove_kv(self) -> (K, V) { - let mut emptied_internal_root = false; - let (old_kv, _) = self.handle.remove_kv_tracking(|| emptied_internal_root = true); - // SAFETY: we consumed the intermediate root borrow, `self.handle`. - let map = unsafe { self.dormant_map.awaken() }; - map.length -= 1; - if emptied_internal_root { - let root = map.root.as_mut().unwrap(); - root.pop_internal_level(); - } - old_kv - } -} - impl<'a, K: 'a, V: 'a> Handle, K, V, marker::LeafOrInternal>, marker::KV> { /// Removes a key/value-pair from the map, and returns that pair, as well as /// the leaf edge corresponding to that former pair. diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs new file mode 100644 index 0000000000000..73a0ca21f6733 --- /dev/null +++ b/library/alloc/src/collections/btree/map/entry.rs @@ -0,0 +1,475 @@ +use core::fmt::{self, Debug}; +use core::marker::PhantomData; +use core::mem; + +use super::super::borrow::DormantMutRef; +use super::super::node::{marker, Handle, InsertResult::*, NodeRef}; +use super::BTreeMap; + +use Entry::*; + +/// A view into a single entry in a map, which may either be vacant or occupied. +/// +/// This `enum` is constructed from the [`entry`] method on [`BTreeMap`]. +/// +/// [`entry`]: BTreeMap::entry +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Entry<'a, K: 'a, V: 'a> { + /// A vacant entry. + #[stable(feature = "rust1", since = "1.0.0")] + Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>), + + /// An occupied entry. + #[stable(feature = "rust1", since = "1.0.0")] + Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>), +} + +#[stable(feature = "debug_btree_map", since = "1.12.0")] +impl Debug for Entry<'_, K, V> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), + Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(), + } + } +} + +/// A view into a vacant entry in a `BTreeMap`. +/// It is part of the [`Entry`] enum. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct VacantEntry<'a, K: 'a, V: 'a> { + pub(super) key: K, + pub(super) handle: Handle, K, V, marker::Leaf>, marker::Edge>, + pub(super) dormant_map: DormantMutRef<'a, BTreeMap>, + + // Be invariant in `K` and `V` + pub(super) _marker: PhantomData<&'a mut (K, V)>, +} + +#[stable(feature = "debug_btree_map", since = "1.12.0")] +impl Debug for VacantEntry<'_, K, V> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("VacantEntry").field(self.key()).finish() + } +} + +/// A view into an occupied entry in a `BTreeMap`. +/// It is part of the [`Entry`] enum. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct OccupiedEntry<'a, K: 'a, V: 'a> { + pub(super) handle: Handle, K, V, marker::LeafOrInternal>, marker::KV>, + pub(super) dormant_map: DormantMutRef<'a, BTreeMap>, + + // Be invariant in `K` and `V` + pub(super) _marker: PhantomData<&'a mut (K, V)>, +} + +#[stable(feature = "debug_btree_map", since = "1.12.0")] +impl Debug for OccupiedEntry<'_, K, V> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish() + } +} + +impl<'a, K: Ord, V> Entry<'a, K, V> { + /// Ensures a value is in the entry by inserting the default if empty, and returns + /// a mutable reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// assert_eq!(map["poneyland"], 12); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn or_insert(self, default: V) -> &'a mut V { + match self { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => entry.insert(default), + } + } + + /// Ensures a value is in the entry by inserting the result of the default function if empty, + /// and returns a mutable reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, String> = BTreeMap::new(); + /// let s = "hoho".to_string(); + /// + /// map.entry("poneyland").or_insert_with(|| s); + /// + /// assert_eq!(map["poneyland"], "hoho".to_string()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn or_insert_with V>(self, default: F) -> &'a mut V { + match self { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => entry.insert(default()), + } + } + + #[unstable(feature = "or_insert_with_key", issue = "71024")] + /// Ensures a value is in the entry by inserting, if empty, the result of the default function, + /// which takes the key as its argument, and returns a mutable reference to the value in the + /// entry. + /// + /// # Examples + /// + /// ``` + /// #![feature(or_insert_with_key)] + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// + /// map.entry("poneyland").or_insert_with_key(|key| key.chars().count()); + /// + /// assert_eq!(map["poneyland"], 9); + /// ``` + #[inline] + pub fn or_insert_with_key V>(self, default: F) -> &'a mut V { + match self { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => { + let value = default(entry.key()); + entry.insert(value) + } + } + } + + /// Returns a reference to this entry's key. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); + /// ``` + #[stable(feature = "map_entry_keys", since = "1.10.0")] + pub fn key(&self) -> &K { + match *self { + Occupied(ref entry) => entry.key(), + Vacant(ref entry) => entry.key(), + } + } + + /// Provides in-place mutable access to an occupied entry before any + /// potential inserts into the map. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// + /// map.entry("poneyland") + /// .and_modify(|e| { *e += 1 }) + /// .or_insert(42); + /// assert_eq!(map["poneyland"], 42); + /// + /// map.entry("poneyland") + /// .and_modify(|e| { *e += 1 }) + /// .or_insert(42); + /// assert_eq!(map["poneyland"], 43); + /// ``` + #[stable(feature = "entry_and_modify", since = "1.26.0")] + pub fn and_modify(self, f: F) -> Self + where + F: FnOnce(&mut V), + { + match self { + Occupied(mut entry) => { + f(entry.get_mut()); + Occupied(entry) + } + Vacant(entry) => Vacant(entry), + } + } +} + +impl<'a, K: Ord, V: Default> Entry<'a, K, V> { + #[stable(feature = "entry_or_default", since = "1.28.0")] + /// Ensures a value is in the entry by inserting the default value if empty, + /// and returns a mutable reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, Option> = BTreeMap::new(); + /// map.entry("poneyland").or_default(); + /// + /// assert_eq!(map["poneyland"], None); + /// ``` + pub fn or_default(self) -> &'a mut V { + match self { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => entry.insert(Default::default()), + } + } +} + +impl<'a, K: Ord, V> VacantEntry<'a, K, V> { + /// Gets a reference to the key that would be used when inserting a value + /// through the VacantEntry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); + /// ``` + #[stable(feature = "map_entry_keys", since = "1.10.0")] + pub fn key(&self) -> &K { + &self.key + } + + /// Take ownership of the key. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// use std::collections::btree_map::Entry; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// + /// if let Entry::Vacant(v) = map.entry("poneyland") { + /// v.into_key(); + /// } + /// ``` + #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")] + pub fn into_key(self) -> K { + self.key + } + + /// Sets the value of the entry with the `VacantEntry`'s key, + /// and returns a mutable reference to it. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// use std::collections::btree_map::Entry; + /// + /// let mut map: BTreeMap<&str, u32> = BTreeMap::new(); + /// + /// if let Entry::Vacant(o) = map.entry("poneyland") { + /// o.insert(37); + /// } + /// assert_eq!(map["poneyland"], 37); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(self, value: V) -> &'a mut V { + let out_ptr = match self.handle.insert_recursing(self.key, value) { + (Fit(_), val_ptr) => { + // Safety: We have consumed self.handle and the handle returned. + let map = unsafe { self.dormant_map.awaken() }; + map.length += 1; + val_ptr + } + (Split(ins), val_ptr) => { + drop(ins.left); + // Safety: We have consumed self.handle and the reference returned. + let map = unsafe { self.dormant_map.awaken() }; + let root = map.root.as_mut().unwrap(); + root.push_internal_level().push(ins.k, ins.v, ins.right); + map.length += 1; + val_ptr + } + }; + // Now that we have finished growing the tree using borrowed references, + // dereference the pointer to a part of it, that we picked up along the way. + unsafe { &mut *out_ptr } + } +} + +impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { + /// Gets a reference to the key in the entry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// map.entry("poneyland").or_insert(12); + /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); + /// ``` + #[stable(feature = "map_entry_keys", since = "1.10.0")] + pub fn key(&self) -> &K { + self.handle.reborrow().into_kv().0 + } + + /// Take ownership of the key and value from the map. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// use std::collections::btree_map::Entry; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// if let Entry::Occupied(o) = map.entry("poneyland") { + /// // We delete the entry from the map. + /// o.remove_entry(); + /// } + /// + /// // If now try to get the value, it will panic: + /// // println!("{}", map["poneyland"]); + /// ``` + #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")] + pub fn remove_entry(self) -> (K, V) { + self.remove_kv() + } + + /// Gets a reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// use std::collections::btree_map::Entry; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// if let Entry::Occupied(o) = map.entry("poneyland") { + /// assert_eq!(o.get(), &12); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get(&self) -> &V { + self.handle.reborrow().into_kv().1 + } + + /// Gets a mutable reference to the value in the entry. + /// + /// If you need a reference to the `OccupiedEntry` that may outlive the + /// destruction of the `Entry` value, see [`into_mut`]. + /// + /// [`into_mut`]: OccupiedEntry::into_mut + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// use std::collections::btree_map::Entry; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// assert_eq!(map["poneyland"], 12); + /// if let Entry::Occupied(mut o) = map.entry("poneyland") { + /// *o.get_mut() += 10; + /// assert_eq!(*o.get(), 22); + /// + /// // We can use the same Entry multiple times. + /// *o.get_mut() += 2; + /// } + /// assert_eq!(map["poneyland"], 24); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get_mut(&mut self) -> &mut V { + self.handle.kv_mut().1 + } + + /// Converts the entry into a mutable reference to its value. + /// + /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`]. + /// + /// [`get_mut`]: OccupiedEntry::get_mut + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// use std::collections::btree_map::Entry; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// assert_eq!(map["poneyland"], 12); + /// if let Entry::Occupied(o) = map.entry("poneyland") { + /// *o.into_mut() += 10; + /// } + /// assert_eq!(map["poneyland"], 22); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_mut(self) -> &'a mut V { + self.handle.into_val_mut() + } + + /// Sets the value of the entry with the `OccupiedEntry`'s key, + /// and returns the entry's old value. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// use std::collections::btree_map::Entry; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// if let Entry::Occupied(mut o) = map.entry("poneyland") { + /// assert_eq!(o.insert(15), 12); + /// } + /// assert_eq!(map["poneyland"], 15); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(&mut self, value: V) -> V { + mem::replace(self.get_mut(), value) + } + + /// Takes the value of the entry out of the map, and returns it. + /// + /// # Examples + /// + /// ``` + /// use std::collections::BTreeMap; + /// use std::collections::btree_map::Entry; + /// + /// let mut map: BTreeMap<&str, usize> = BTreeMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// if let Entry::Occupied(o) = map.entry("poneyland") { + /// assert_eq!(o.remove(), 12); + /// } + /// // If we try to get "poneyland"'s value, it'll panic: + /// // println!("{}", map["poneyland"]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn remove(self) -> V { + self.remove_kv().1 + } + + // Body of `remove_entry`, separate to keep the above implementations short. + pub(super) fn remove_kv(self) -> (K, V) { + let mut emptied_internal_root = false; + let (old_kv, _) = self.handle.remove_kv_tracking(|| emptied_internal_root = true); + // SAFETY: we consumed the intermediate root borrow, `self.handle`. + let map = unsafe { self.dormant_map.awaken() }; + map.length -= 1; + if emptied_internal_root { + let root = map.root.as_mut().unwrap(); + root.pop_internal_level(); + } + old_kv + } +} diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index bda9e0f57841c..33e85dc5e2a11 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -737,6 +737,7 @@ impl Step for Tidy { let mut cmd = builder.tool_cmd(Tool::Tidy); cmd.arg(&builder.src); cmd.arg(&builder.initial_cargo); + cmd.arg(&builder.out); if builder.is_verbose() { cmd.arg("--verbose"); } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index a163899839d0e..8c8a00d47bc07 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1557,11 +1557,7 @@ h4 > .notable-traits { } @media (max-width: 416px) { - #titles { - height: 73px; - } - - #titles > div { + #titles, #titles > div { height: 73px; } } diff --git a/src/test/ui/coherence/coherence-all-remote.stderr b/src/test/ui/coherence/coherence-all-remote.stderr index 6ecfb2c5eb0e3..7eca417533954 100644 --- a/src/test/ui/coherence/coherence-all-remote.stderr +++ b/src/test/ui/coherence/coherence-all-remote.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Remote1 for isize { } | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-bigint-param.stderr b/src/test/ui/coherence/coherence-bigint-param.stderr index d431c5f4b5251..e8d74c917e465 100644 --- a/src/test/ui/coherence/coherence-bigint-param.stderr +++ b/src/test/ui/coherence/coherence-bigint-param.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be covered by another type when it appears LL | impl Remote1 for T { } | ^ type parameter `T` must be covered by another type when it appears before the first local type (`BigInt`) | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-cross-crate-conflict.stderr b/src/test/ui/coherence/coherence-cross-crate-conflict.stderr index 5381053979f26..827d26ab43443 100644 --- a/src/test/ui/coherence/coherence-cross-crate-conflict.stderr +++ b/src/test/ui/coherence/coherence-cross-crate-conflict.stderr @@ -13,7 +13,7 @@ error[E0210]: type parameter `A` must be used as the type parameter for some loc LL | impl Foo for A { | ^ type parameter `A` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/coherence-lone-type-parameter.stderr b/src/test/ui/coherence/coherence-lone-type-parameter.stderr index 2c3b4fc3ad2a8..ef5b088365381 100644 --- a/src/test/ui/coherence/coherence-lone-type-parameter.stderr +++ b/src/test/ui/coherence/coherence-lone-type-parameter.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Remote for T { } | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to previous error diff --git a/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr index 8a951d407ca46..249a5c44c79cd 100644 --- a/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr +++ b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Remote for Box { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to previous error diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr index c5759244eff49..95a20cc5b0f5c 100644 --- a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Remote1 for Box { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) @@ -13,7 +13,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl<'a, T> Remote1 for &'a T { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr index e8663fd7d820d..aed184767a0bd 100644 --- a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Remote1 for T { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to previous error diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr index 639bee2b8ec74..73b1e2c6ed248 100644 --- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Remote1> for u32 { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) @@ -13,7 +13,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl<'a, T> Remote1<&'a T> for u32 { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr index 0b6c81b53cd5f..5f89a7aa469c1 100644 --- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl<'a, T> Remote1> for &'a T { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) @@ -13,7 +13,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl<'a, T> Remote1<&'a T> for Box { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr index fe40490822e0f..45559d8b62d37 100644 --- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Remote1> for T { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) @@ -13,7 +13,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl<'a, T> Remote1<&'a T> for T { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr index 1eaef59b3f880..f94f04c8df5c1 100644 --- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be covered by another type when it appears LL | impl Remote2, Local> for u32 { | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) @@ -13,7 +13,7 @@ error[E0210]: type parameter `T` must be covered by another type when it appears LL | impl<'a, T> Remote2<&'a T, Local> for u32 { | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr index 4d39186d494c9..e68f2fe585637 100644 --- a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be covered by another type when it appears LL | impl Remote1 for Box { | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) @@ -13,7 +13,7 @@ error[E0210]: type parameter `T` must be covered by another type when it appears LL | impl Remote1 for &T { | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr index d74be4cec728d..d97e85dcb3c3e 100644 --- a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be covered by another type when it appears LL | impl Remote1 for T { | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last error: aborting due to previous error diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr index b26feb4914c63..44e3b7eedb40c 100644 --- a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Remote1 for u32 { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to previous error diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr index 5e8cc552c9834..80fb5dbec8662 100644 --- a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Remote1 for Box { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error[E0210]: type parameter `B` must be used as the type parameter for some local type (e.g., `MyStruct`) @@ -13,7 +13,7 @@ error[E0210]: type parameter `B` must be used as the type parameter for some loc LL | impl<'a, A, B> Remote1 for &'a B { | ^ type parameter `B` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr index d3226d33beec7..ff72969dc52ae 100644 --- a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Remote1 for T { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0424.rs b/src/test/ui/error-codes/E0424.rs index fa0c86ecf4894..6e531942cad52 100644 --- a/src/test/ui/error-codes/E0424.rs +++ b/src/test/ui/error-codes/E0424.rs @@ -10,6 +10,10 @@ impl Foo { fn baz(_: i32) { self.bar(); //~ ERROR E0424 } + + fn qux() { + let _ = || 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 9b8a29e827249..20b7a4cb6ece6 100644 --- a/src/test/ui/error-codes/E0424.stderr +++ b/src/test/ui/error-codes/E0424.stderr @@ -24,14 +24,27 @@ help: add a `self` receiver parameter to make the associated `fn` a method LL | fn baz(&self, _: i32) { | ^^^^^^ +error[E0424]: expected value, found module `self` + --> $DIR/E0424.rs:15:20 + | +LL | fn qux() { + | --- this function doesn't have a `self` parameter +LL | let _ = || 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 qux(&self) { + | ^^^^^ + error[E0424]: expected unit struct, unit variant or constant, found module `self` - --> $DIR/E0424.rs:16:9 + --> $DIR/E0424.rs:20:9 | 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 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0424`. diff --git a/src/test/ui/error-codes/e0119/issue-28981.stderr b/src/test/ui/error-codes/e0119/issue-28981.stderr index c22cc65c87fce..e12dd7623310d 100644 --- a/src/test/ui/error-codes/e0119/issue-28981.stderr +++ b/src/test/ui/error-codes/e0119/issue-28981.stderr @@ -14,7 +14,7 @@ error[E0210]: type parameter `Foo` must be used as the type parameter for some l LL | impl Deref for Foo { } | ^^^ type parameter `Foo` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-41974.stderr b/src/test/ui/issues/issue-41974.stderr index f1342181b37d9..a092c94b9d563 100644 --- a/src/test/ui/issues/issue-41974.stderr +++ b/src/test/ui/issues/issue-41974.stderr @@ -21,7 +21,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl Drop for T where T: A { | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-5099.rs b/src/test/ui/issues/issue-5099.rs index ee134835c37ed..b5abccb4b19f9 100644 --- a/src/test/ui/issues/issue-5099.rs +++ b/src/test/ui/issues/issue-5099.rs @@ -5,6 +5,9 @@ trait B { fn b(x: i32) { this.b(x); //~ ERROR cannot find value `this` in this scope } + fn c() { + let _ = || this.a; //~ 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 b52fd28b2b575..b39c4a9f272d0 100644 --- a/src/test/ui/issues/issue-5099.stderr +++ b/src/test/ui/issues/issue-5099.stderr @@ -28,6 +28,21 @@ help: if you meant to use `self`, you are also missing a `self` receiver argumen LL | fn b(&self, x: i32) { | ^^^^^^ -error: aborting due to 2 previous errors +error[E0425]: cannot find value `this` in this scope + --> $DIR/issue-5099.rs:9:20 + | +LL | let _ = || this.a; + | ^^^^ not found in this scope + | +help: you might have meant to use `self` here instead + | +LL | let _ = || self.a; + | ^^^^ +help: if you meant to use `self`, you are also missing a `self` receiver argument + | +LL | fn c(&self) { + | ^^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/orphan-check-diagnostics.stderr b/src/test/ui/orphan-check-diagnostics.stderr index c84d401898c91..7a7cea56307de 100644 --- a/src/test/ui/orphan-check-diagnostics.stderr +++ b/src/test/ui/orphan-check-diagnostics.stderr @@ -4,7 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc LL | impl RemoteTrait for T where T: LocalTrait {} | ^ type parameter `T` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to previous error diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/meta.rs b/src/test/ui/rfc-2126-extern-absolute-paths/meta.rs deleted file mode 100644 index 1fb5878ca2ace..0000000000000 --- a/src/test/ui/rfc-2126-extern-absolute-paths/meta.rs +++ /dev/null @@ -1,7 +0,0 @@ -// edition:2018 - -// Tests that `meta` is allowed, even if the crate doesn't exist -// yet (i.e., it causes a different error than `not-allowed.rs`). -use meta; //~ ERROR can't find crate for `meta` - -fn main() {} diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/meta.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/meta.stderr deleted file mode 100644 index eb4b9dea41bdd..0000000000000 --- a/src/test/ui/rfc-2126-extern-absolute-paths/meta.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0463]: can't find crate for `meta` - --> $DIR/meta.rs:5:5 - | -LL | use meta; - | ^^^^ can't find crate - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0463`. diff --git a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr index cb893c40c3252..eafbd2ad0725b 100644 --- a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr +++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr @@ -14,7 +14,7 @@ error[E0210]: type parameter `F` must be used as the type parameter for some loc LL | impl FnOnce<()> for &F { | ^ type parameter `F` must be used as the type parameter for some local type | - = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 2 previous errors diff --git a/src/tools/clippy/clippy_lints/src/utils/paths.rs b/src/tools/clippy/clippy_lints/src/utils/paths.rs index 277da9d3f3a27..5e769c690a690 100644 --- a/src/tools/clippy/clippy_lints/src/utils/paths.rs +++ b/src/tools/clippy/clippy_lints/src/utils/paths.rs @@ -14,7 +14,7 @@ pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "Bina pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"]; pub const BOX: [&str; 3] = ["alloc", "boxed", "Box"]; pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"]; -pub const BTREEMAP_ENTRY: [&str; 5] = ["alloc", "collections", "btree", "map", "Entry"]; +pub const BTREEMAP_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "entry", "Entry"]; pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"]; pub const CLONE_TRAIT: [&str; 3] = ["core", "clone", "Clone"]; pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"]; diff --git a/src/tools/linkchecker/linkcheck.sh b/src/tools/linkchecker/linkcheck.sh index bbccc17e494c8..b68053c76befc 100755 --- a/src/tools/linkchecker/linkcheck.sh +++ b/src/tools/linkchecker/linkcheck.sh @@ -34,6 +34,9 @@ then exit 1 fi +# Avoid failure caused by newer mdbook. +export MDBOOK_OUTPUT__HTML__INPUT_404="" + book_name="" # Iterative will avoid cleaning up, so you can quickly run it repeatedly. iterative=0 diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index 589be26dc27ed..62cfa85577f98 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -9,19 +9,56 @@ use std::path::Path; // All files are executable on Windows, so just check on Unix. #[cfg(windows)] -pub fn check(_path: &Path, _bad: &mut bool) {} +pub fn check(_path: &Path, _output: &Path, _bad: &mut bool) {} #[cfg(unix)] -pub fn check(path: &Path, bad: &mut bool) { +pub fn check(path: &Path, output: &Path, bad: &mut bool) { use std::fs; use std::os::unix::prelude::*; use std::process::{Command, Stdio}; - if let Ok(contents) = fs::read_to_string("/proc/version") { - // Probably on Windows Linux Subsystem or Docker via VirtualBox, - // all files will be marked as executable, so skip checking. - if contents.contains("Microsoft") || contents.contains("boot2docker") { - return; + fn is_executable(path: &Path) -> std::io::Result { + Ok(path.metadata()?.mode() & 0o111 != 0) + } + + // We want to avoid false positives on filesystems that do not support the + // executable bit. This occurs on some versions of Window's linux subsystem, + // for example. + // + // We try to create the temporary file first in the src directory, which is + // the preferred location as it's most likely to be on the same filesystem, + // and then in the output (`build`) directory if that fails. Sometimes we + // see the source directory mounted as read-only which means we can't + // readily create a file there to test. + // + // See #36706 and #74753 for context. + let mut temp_path = path.join("tidy-test-file"); + match fs::File::create(&temp_path).or_else(|_| { + temp_path = output.join("tidy-test-file"); + fs::File::create(&temp_path) + }) { + Ok(file) => { + let exec = is_executable(&temp_path).unwrap_or(false); + std::mem::drop(file); + std::fs::remove_file(&temp_path).expect("Deleted temp file"); + if exec { + // If the file is executable, then we assume that this + // filesystem does not track executability, so skip this check. + return; + } + } + Err(e) => { + // If the directory is read-only or we otherwise don't have rights, + // just don't run this check. + // + // 30 is the "Read-only filesystem" code at least in one CI + // environment. + if e.raw_os_error() == Some(30) { + eprintln!("tidy: Skipping binary file check, read-only filesystem"); + return; + } + + panic!("unable to create temporary file `{:?}`: {:?}", temp_path, e); } } @@ -36,8 +73,7 @@ pub fn check(path: &Path, bad: &mut bool) { return; } - let metadata = t!(entry.metadata(), file); - if metadata.mode() & 0o111 != 0 { + if t!(is_executable(&file), file) { let rel_path = file.strip_prefix(path).unwrap(); let git_friendly_path = rel_path.to_str().unwrap().replace("\\", "/"); let output = Command::new("git") diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 36c9e58eb9a87..e1525f8e1bf23 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -13,6 +13,8 @@ use std::process; fn main() { let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into(); let cargo: PathBuf = env::args_os().nth(2).expect("need path to cargo").into(); + let output_directory: PathBuf = + env::args_os().nth(3).expect("need path to output directory").into(); let src_path = root_path.join("src"); let library_path = root_path.join("library"); @@ -36,9 +38,9 @@ fn main() { unit_tests::check(&library_path, &mut bad); // Checks that need to be done for both the compiler and std libraries. - bins::check(&src_path, &mut bad); - bins::check(&compiler_path, &mut bad); - bins::check(&library_path, &mut bad); + bins::check(&src_path, &output_directory, &mut bad); + bins::check(&compiler_path, &output_directory, &mut bad); + bins::check(&library_path, &output_directory, &mut bad); style::check(&src_path, &mut bad); style::check(&compiler_path, &mut bad);