From 13dfbb64d313137b7d3c33067910e90f27bc6345 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi Date: Thu, 6 Aug 2020 11:53:09 +0600 Subject: [PATCH 01/15] Suggest imports of unresolved macros --- compiler/rustc_resolve/src/diagnostics.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 612bc3e74911c..42af8a2fb0edb 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -929,6 +929,10 @@ impl<'a> Resolver<'a> { ); self.add_typo_suggestion(err, suggestion, ident.span); + let import_suggestions = + self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, |_| true); + show_candidates(err, None, &import_suggestions, false, true); + if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) { let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident); err.span_note(ident.span, &msg); From 479298e05e8177b171c6d6bcd35fc7553b424bee Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi Date: Thu, 6 Aug 2020 16:42:06 +0600 Subject: [PATCH 02/15] Re-run tests with --bless --- src/test/ui/empty/empty-macro-use.stderr | 3 +++ src/test/ui/hygiene/no_implicit_prelude-2018.stderr | 3 +++ src/test/ui/hygiene/no_implicit_prelude.stderr | 3 +++ src/test/ui/issues/issue-11692-2.stderr | 3 +++ src/test/ui/macros/macro-use-wrong-name.stderr | 3 +++ src/test/ui/missing/missing-macro-use.stderr | 3 +++ src/test/ui/proc-macro/derive-helper-shadowing.stderr | 4 ++++ src/test/ui/proc-macro/macro-namespace-reserved-2.stderr | 6 ++++++ 8 files changed, 28 insertions(+) diff --git a/src/test/ui/empty/empty-macro-use.stderr b/src/test/ui/empty/empty-macro-use.stderr index 8e3e06896ee78..700f6616af40f 100644 --- a/src/test/ui/empty/empty-macro-use.stderr +++ b/src/test/ui/empty/empty-macro-use.stderr @@ -3,6 +3,9 @@ error: cannot find macro `macro_two` in this scope | LL | macro_two!(); | ^^^^^^^^^ + | + = note: consider importing this macro: + two_macros::macro_two error: aborting due to previous error diff --git a/src/test/ui/hygiene/no_implicit_prelude-2018.stderr b/src/test/ui/hygiene/no_implicit_prelude-2018.stderr index f31b75238dffe..02ddc391f6e3c 100644 --- a/src/test/ui/hygiene/no_implicit_prelude-2018.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude-2018.stderr @@ -3,6 +3,9 @@ error: cannot find macro `print` in this scope | LL | print!(); | ^^^^^ + | + = note: consider importing this macro: + std::print error: aborting due to previous error diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr index 3c0c0450774e9..843dee2478b3f 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -4,6 +4,9 @@ error: cannot find macro `panic` in this scope LL | assert_eq!(0, 0); | ^^^^^^^^^^^^^^^^^ | + = note: consider importing one of these items: + core::panic + std::panic = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0433]: failed to resolve: use of undeclared type `Vec` diff --git a/src/test/ui/issues/issue-11692-2.stderr b/src/test/ui/issues/issue-11692-2.stderr index f021943da32da..22b4dbce54a1a 100644 --- a/src/test/ui/issues/issue-11692-2.stderr +++ b/src/test/ui/issues/issue-11692-2.stderr @@ -3,6 +3,9 @@ error: cannot find macro `test` in this scope | LL | concat!(test!()); | ^^^^ + | + = note: consider importing this attribute macro: + std::prelude::v1::test error: aborting due to previous error diff --git a/src/test/ui/macros/macro-use-wrong-name.stderr b/src/test/ui/macros/macro-use-wrong-name.stderr index 74fb519cc82ff..888fb913fb71c 100644 --- a/src/test/ui/macros/macro-use-wrong-name.stderr +++ b/src/test/ui/macros/macro-use-wrong-name.stderr @@ -8,6 +8,9 @@ LL | macro_two!(); | LL | macro_rules! macro_one { () => ("one") } | ---------------------- similarly named macro `macro_one` defined here + | + = note: consider importing this macro: + two_macros::macro_two error: aborting due to previous error diff --git a/src/test/ui/missing/missing-macro-use.stderr b/src/test/ui/missing/missing-macro-use.stderr index 711e249d2bca1..ced062269df68 100644 --- a/src/test/ui/missing/missing-macro-use.stderr +++ b/src/test/ui/missing/missing-macro-use.stderr @@ -3,6 +3,9 @@ error: cannot find macro `macro_two` in this scope | LL | macro_two!(); | ^^^^^^^^^ + | + = note: consider importing this macro: + two_macros::macro_two error: aborting due to previous error diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr index f82f49aa77526..6aff0cb8e9ca5 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr @@ -16,6 +16,8 @@ error: cannot find attribute `empty_helper` in this scope LL | #[derive(GenHelperUse)] | ^^^^^^^^^^^^ | + = note: consider importing this attribute macro: + empty_helper = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find attribute `empty_helper` in this scope @@ -27,6 +29,8 @@ LL | #[empty_helper] LL | gen_helper_use!(); | ------------------ in this macro invocation | + = note: consider importing this attribute macro: + crate::empty_helper = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `empty_helper` is ambiguous (name vs any other name during import resolution) diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr index a617319faea80..8073fafb0d8f8 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -93,12 +93,18 @@ error: cannot find macro `my_macro_attr` in this scope | LL | my_macro_attr!(); | ^^^^^^^^^^^^^ + | + = note: consider importing this attribute macro: + my_macro_attr error: cannot find macro `MyTrait` in this scope --> $DIR/macro-namespace-reserved-2.rs:33:5 | LL | MyTrait!(); | ^^^^^^^ + | + = note: consider importing this derive macro: + MyTrait error: cannot find attribute `my_macro` in this scope --> $DIR/macro-namespace-reserved-2.rs:38:3 From ea7cf6106864ce7929eb9f3cfe580f05ee418ac8 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi Date: Sat, 29 Aug 2020 01:01:29 +0600 Subject: [PATCH 03/15] Don't suggest macros that out of scope --- compiler/rustc_resolve/src/diagnostics.rs | 11 +++++++++-- src/test/ui/issues/issue-11692-2.stderr | 3 --- src/test/ui/proc-macro/derive-helper-shadowing.stderr | 4 ---- .../ui/proc-macro/macro-namespace-reserved-2.stderr | 6 ------ 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 42af8a2fb0edb..0ad057822b36e 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -929,8 +929,15 @@ impl<'a> Resolver<'a> { ); self.add_typo_suggestion(err, suggestion, ident.span); - let import_suggestions = - self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, |_| true); + let import_suggestions = self.lookup_import_candidates( + ident, + Namespace::MacroNS, + parent_scope, + |res| match res { + Res::Def(DefKind::Macro(MacroKind::Bang), _) => true, + _ => false, + }, + ); show_candidates(err, None, &import_suggestions, false, true); if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) { diff --git a/src/test/ui/issues/issue-11692-2.stderr b/src/test/ui/issues/issue-11692-2.stderr index 22b4dbce54a1a..f021943da32da 100644 --- a/src/test/ui/issues/issue-11692-2.stderr +++ b/src/test/ui/issues/issue-11692-2.stderr @@ -3,9 +3,6 @@ error: cannot find macro `test` in this scope | LL | concat!(test!()); | ^^^^ - | - = note: consider importing this attribute macro: - std::prelude::v1::test error: aborting due to previous error diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr index 6aff0cb8e9ca5..f82f49aa77526 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr @@ -16,8 +16,6 @@ error: cannot find attribute `empty_helper` in this scope LL | #[derive(GenHelperUse)] | ^^^^^^^^^^^^ | - = note: consider importing this attribute macro: - empty_helper = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find attribute `empty_helper` in this scope @@ -29,8 +27,6 @@ LL | #[empty_helper] LL | gen_helper_use!(); | ------------------ in this macro invocation | - = note: consider importing this attribute macro: - crate::empty_helper = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `empty_helper` is ambiguous (name vs any other name during import resolution) diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr index 8073fafb0d8f8..a617319faea80 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -93,18 +93,12 @@ error: cannot find macro `my_macro_attr` in this scope | LL | my_macro_attr!(); | ^^^^^^^^^^^^^ - | - = note: consider importing this attribute macro: - my_macro_attr error: cannot find macro `MyTrait` in this scope --> $DIR/macro-namespace-reserved-2.rs:33:5 | LL | MyTrait!(); | ^^^^^^^ - | - = note: consider importing this derive macro: - MyTrait error: cannot find attribute `my_macro` in this scope --> $DIR/macro-namespace-reserved-2.rs:38:3 From 54bf8a681bededa6c7e09f4c1da3cb68efb885a3 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 11 Oct 2020 14:56:12 -0400 Subject: [PATCH 04/15] Don't link to nightly primitives on stable channel I am not sure how to test this. --- src/librustdoc/clean/types.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 1e07f8e2eac24..f81c6c3df76af 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -14,6 +14,7 @@ use rustc_ast::util::comments::beautify_doc_string; use rustc_ast::{self as ast, AttrStyle}; use rustc_ast::{FloatTy, IntTy, UintTy}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_feature::UnstableFeatures; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -698,9 +699,13 @@ impl Attributes { "../".repeat(depth) } Some(&(_, _, ExternalLocation::Remote(ref s))) => s.to_string(), - Some(&(_, _, ExternalLocation::Unknown)) | None => { - String::from("https://doc.rust-lang.org/nightly") - } + Some(&(_, _, ExternalLocation::Unknown)) | None => String::from( + if UnstableFeatures::from_environment().is_nightly_build() { + "https://doc.rust-lang.org/nightly" + } else { + "https://doc.rust-lang.org" + }, + ), }; // This is a primitive so the url is done "by hand". let tail = fragment.find('#').unwrap_or_else(|| fragment.len()); From 4b96049da2329ba6e9a7fd4cd8224417fb4baede Mon Sep 17 00:00:00 2001 From: Jacob Hughes Date: Mon, 12 Oct 2020 08:44:53 -0400 Subject: [PATCH 05/15] BTreeMap: refactor Entry out of map.rs into its own file btree/map.rs is approaching the 3000 line mark, splitting out the entry code buys about 500 lines of headroom --- library/alloc/src/collections/btree/map.rs | 473 +---------------- .../alloc/src/collections/btree/map/entry.rs | 475 ++++++++++++++++++ 2 files changed, 480 insertions(+), 468 deletions(-) create mode 100644 library/alloc/src/collections/btree/map/entry.rs 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 + } +} From 8c0c7ec4ec6c4f305c229d74f74f08f86a59fc69 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Tue, 13 Oct 2020 15:57:31 +0200 Subject: [PATCH 06/15] Use fdatasync for File::sync_data on more OSes Add support for the following OSes: * Android * FreeBSD: https://www.freebsd.org/cgi/man.cgi?query=fdatasync&sektion=2 * OpenBSD: https://man.openbsd.org/OpenBSD-5.8/fsync.2 * NetBSD: https://man.netbsd.org/fdatasync.2 * illumos: https://illumos.org/man/3c/fdatasync --- library/std/src/sys/unix/fs.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 566ac0920dc8f..576cc24cc0f64 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -752,11 +752,25 @@ impl File { unsafe fn os_datasync(fd: c_int) -> c_int { libc::fcntl(fd, libc::F_FULLFSYNC) } - #[cfg(target_os = "linux")] + #[cfg(any( + target_os = "freebsd", + target_os = "linux", + target_os = "android", + target_os = "netbsd", + target_os = "openbsd" + ))] unsafe fn os_datasync(fd: c_int) -> c_int { libc::fdatasync(fd) } - #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "linux")))] + #[cfg(not(any( + target_os = "android", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd" + )))] unsafe fn os_datasync(fd: c_int) -> c_int { libc::fsync(fd) } From adf31e95e44ff0b7fbc798fe2b8cc5a42a3abf4b Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 12 Oct 2020 16:43:49 +0100 Subject: [PATCH 07/15] resolve: suggest variants with placeholders This commit improves the diagnostic modified in rust-lang/rust#77341 to suggest not only those variants which do not have fields, but those with fields (by suggesting with placeholders). Signed-off-by: David Wood --- .../rustc_resolve/src/late/diagnostics.rs | 146 +++++++++++------- ...issue-43871-enum-instead-of-variant.stderr | 21 +++ src/test/ui/glob-resolve1.stderr | 12 +- src/test/ui/issues/issue-73427.stderr | 98 +++++++++++- src/test/ui/resolve/privacy-enum-ctor.stderr | 112 ++++++++++++-- 5 files changed, 311 insertions(+), 78 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index bee05e7738280..8ef99f36a04af 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1330,58 +1330,32 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let suggest_only_tuple_variants = matches!(source, PathSource::TupleStruct(..)) || source.is_call(); - let mut suggestable_variants = if suggest_only_tuple_variants { + if suggest_only_tuple_variants { // Suggest only tuple variants regardless of whether they have fields and do not // suggest path with added parenthesis. - variants + let mut suggestable_variants = variants .iter() .filter(|(.., kind)| *kind == CtorKind::Fn) .map(|(variant, ..)| path_names_to_string(variant)) - .collect::>() - } else { - variants - .iter() - .filter(|(_, def_id, kind)| { - // Suggest only variants that have no fields (these can definitely - // be constructed). - let has_fields = - self.r.field_names.get(&def_id).map(|f| f.is_empty()).unwrap_or(false); - match kind { - CtorKind::Const => true, - CtorKind::Fn | CtorKind::Fictive if has_fields => true, - _ => false, - } - }) - .map(|(variant, _, kind)| (path_names_to_string(variant), kind)) - .map(|(variant_str, kind)| { - // Add constructor syntax where appropriate. - match kind { - CtorKind::Const => variant_str, - CtorKind::Fn => format!("({}())", variant_str), - CtorKind::Fictive => format!("({} {{}})", variant_str), - } - }) - .collect::>() - }; + .collect::>(); - let non_suggestable_variant_count = variants.len() - suggestable_variants.len(); + let non_suggestable_variant_count = variants.len() - suggestable_variants.len(); - if !suggestable_variants.is_empty() { - let msg = if non_suggestable_variant_count == 0 && suggestable_variants.len() == 1 { - "try using the enum's variant" - } else { - "try using one of the enum's variants" - }; + if !suggestable_variants.is_empty() { + let msg = if non_suggestable_variant_count == 0 && suggestable_variants.len() == 1 { + "try using the enum's variant" + } else { + "try using one of the enum's variants" + }; - err.span_suggestions( - span, - msg, - suggestable_variants.drain(..), - Applicability::MaybeIncorrect, - ); - } + err.span_suggestions( + span, + msg, + suggestable_variants.drain(..), + Applicability::MaybeIncorrect, + ); + } - if suggest_only_tuple_variants { let source_msg = if source.is_call() { "to construct" } else if matches!(source, PathSource::TupleStruct(..)) { @@ -1408,24 +1382,76 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { )); } } else { - let made_suggestion = non_suggestable_variant_count != variants.len(); - if made_suggestion { - if non_suggestable_variant_count == 1 { - err.help( - "you might have meant to use the enum's other variant that has fields", - ); - } else if non_suggestable_variant_count >= 1 { - err.help( - "you might have meant to use one of the enum's other variants that \ - have fields", - ); - } - } else { - if non_suggestable_variant_count == 1 { - err.help("you might have meant to use the enum's variant"); - } else if non_suggestable_variant_count >= 1 { - err.help("you might have meant to use one of the enum's variants"); + let needs_placeholder = |def_id: DefId, kind: CtorKind| { + let has_no_fields = + self.r.field_names.get(&def_id).map(|f| f.is_empty()).unwrap_or(false); + match kind { + CtorKind::Const => false, + CtorKind::Fn | CtorKind::Fictive if has_no_fields => false, + _ => true, } + }; + + let mut suggestable_variants = variants + .iter() + .filter(|(_, def_id, kind)| !needs_placeholder(*def_id, *kind)) + .map(|(variant, _, kind)| (path_names_to_string(variant), kind)) + .map(|(variant, kind)| match kind { + CtorKind::Const => variant, + CtorKind::Fn => format!("({}())", variant), + CtorKind::Fictive => format!("({} {{}})", variant), + }) + .collect::>(); + + if !suggestable_variants.is_empty() { + let msg = if suggestable_variants.len() == 1 { + "you might have meant to use the following enum variant" + } else { + "you might have meant to use one of the following enum variants" + }; + + err.span_suggestions( + span, + msg, + suggestable_variants.drain(..), + Applicability::MaybeIncorrect, + ); + } + + let mut suggestable_variants_with_placeholders = variants + .iter() + .filter(|(_, def_id, kind)| needs_placeholder(*def_id, *kind)) + .map(|(variant, _, kind)| (path_names_to_string(variant), kind)) + .filter_map(|(variant, kind)| match kind { + CtorKind::Fn => Some(format!("({}(/* fields */))", variant)), + CtorKind::Fictive => Some(format!("({} {{ /* fields */ }})", variant)), + _ => None, + }) + .collect::>(); + + if !suggestable_variants_with_placeholders.is_empty() { + let msg = match ( + suggestable_variants.is_empty(), + suggestable_variants_with_placeholders.len(), + ) { + (true, 1) => "the following enum variant is available", + (true, _) => "the following enum variants are available", + (false, 1) => "alternatively, the following enum variant is available", + (false, _) => "alternatively, the following enum variants are also available", + }; + + err.span_suggestions( + span, + msg, + suggestable_variants_with_placeholders.drain(..), + Applicability::HasPlaceholders, + ); + } + }; + + if def_id.is_local() { + if let Some(span) = self.def_span(def_id) { + err.span_note(span, "the enum is defined here"); } } } diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr index e1325b789d2e9..62a7649e2adf7 100644 --- a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr +++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr @@ -21,6 +21,11 @@ LL | if let Example(_) = y { | ^^^^^^^ help: try using one of the enum's variants: `Example::Ex` | = help: you might have meant to match against the enum's non-tuple variant +note: the enum is defined here + --> $DIR/issue-43871-enum-instead-of-variant.rs:1:1 + | +LL | enum Example { Ex(String), NotEx } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0423]: expected function, tuple struct or tuple variant, found enum `Void` --> $DIR/issue-43871-enum-instead-of-variant.rs:31:13 @@ -29,6 +34,11 @@ LL | let y = Void(); | ^^^^ | = help: the enum has no tuple variants to construct +note: the enum is defined here + --> $DIR/issue-43871-enum-instead-of-variant.rs:3:1 + | +LL | enum Void {} + | ^^^^^^^^^^^^ error[E0423]: expected function, tuple struct or tuple variant, found enum `ManyVariants` --> $DIR/issue-43871-enum-instead-of-variant.rs:33:13 @@ -38,6 +48,17 @@ LL | let z = ManyVariants(); | = help: the enum has no tuple variants to construct = help: you might have meant to construct one of the enum's non-tuple variants +note: the enum is defined here + --> $DIR/issue-43871-enum-instead-of-variant.rs:5:1 + | +LL | / enum ManyVariants { +LL | | One, +LL | | Two, +LL | | Three, +... | +LL | | Ten, +LL | | } + | |_^ error: aborting due to 5 previous errors diff --git a/src/test/ui/glob-resolve1.stderr b/src/test/ui/glob-resolve1.stderr index 3c818f3ae48ea..cd128c1ea0b48 100644 --- a/src/test/ui/glob-resolve1.stderr +++ b/src/test/ui/glob-resolve1.stderr @@ -24,7 +24,17 @@ error[E0423]: expected value, found enum `B` --> $DIR/glob-resolve1.rs:24:5 | LL | B; - | ^ help: try using the enum's variant: `B::B1` + | ^ + | +note: the enum is defined here + --> $DIR/glob-resolve1.rs:12:5 + | +LL | pub enum B { B1 } + | ^^^^^^^^^^^^^^^^^ +help: you might have meant to use the following enum variant + | +LL | B::B1; + | ^^^^^ error[E0425]: cannot find value `C` in this scope --> $DIR/glob-resolve1.rs:25:5 diff --git a/src/test/ui/issues/issue-73427.stderr b/src/test/ui/issues/issue-73427.stderr index 88d19943f0226..4da5305e6870f 100644 --- a/src/test/ui/issues/issue-73427.stderr +++ b/src/test/ui/issues/issue-73427.stderr @@ -4,8 +4,18 @@ error[E0423]: expected value, found enum `A` LL | A.foo(); | ^ | - = help: you might have meant to use one of the enum's other variants that have fields -help: try using one of the enum's variants +note: the enum is defined here + --> $DIR/issue-73427.rs:1:1 + | +LL | / enum A { +LL | | StructWithFields { x: () }, +LL | | TupleWithFields(()), +LL | | Struct {}, +LL | | Tuple(), +LL | | Unit, +LL | | } + | |_^ +help: you might have meant to use one of the following enum variants | LL | (A::Struct {}).foo(); | ^^^^^^^^^^^^^^ @@ -13,6 +23,12 @@ LL | (A::Tuple()).foo(); | ^^^^^^^^^^^^ LL | A::Unit.foo(); | ^^^^^^^ +help: the following enum variants are available + | +LL | (A::StructWithFields { /* fields */ }).foo(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (A::TupleWithFields(/* fields */)).foo(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0423]: expected value, found enum `B` --> $DIR/issue-73427.rs:31:5 @@ -20,23 +36,69 @@ error[E0423]: expected value, found enum `B` LL | B.foo(); | ^ | - = help: you might have meant to use one of the enum's variants +note: the enum is defined here + --> $DIR/issue-73427.rs:9:1 + | +LL | / enum B { +LL | | StructWithFields { x: () }, +LL | | TupleWithFields(()), +LL | | } + | |_^ +help: the following enum variants are available + | +LL | (B::StructWithFields { /* fields */ }).foo(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (B::TupleWithFields(/* fields */)).foo(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0423]: expected value, found enum `C` --> $DIR/issue-73427.rs:33:5 | LL | C.foo(); - | ^ help: try using one of the enum's variants: `C::Unit` + | ^ + | +note: the enum is defined here + --> $DIR/issue-73427.rs:14:1 | - = help: you might have meant to use one of the enum's other variants that have fields +LL | / enum C { +LL | | StructWithFields { x: () }, +LL | | TupleWithFields(()), +LL | | Unit, +LL | | } + | |_^ +help: you might have meant to use the following enum variant + | +LL | C::Unit.foo(); + | ^^^^^^^ +help: the following enum variants are available + | +LL | (C::StructWithFields { /* fields */ }).foo(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (C::TupleWithFields(/* fields */)).foo(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0423]: expected value, found enum `D` --> $DIR/issue-73427.rs:35:5 | LL | D.foo(); - | ^ help: try using one of the enum's variants: `D::Unit` + | ^ + | +note: the enum is defined here + --> $DIR/issue-73427.rs:20:1 + | +LL | / enum D { +LL | | TupleWithFields(()), +LL | | Unit, +LL | | } + | |_^ +help: you might have meant to use the following enum variant | - = help: you might have meant to use the enum's other variant that has fields +LL | D::Unit.foo(); + | ^^^^^^^ +help: the following enum variant is available + | +LL | (D::TupleWithFields(/* fields */)).foo(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0423]: expected function, tuple struct or tuple variant, found enum `A` --> $DIR/issue-73427.rs:40:13 @@ -45,6 +107,17 @@ LL | let x = A(3); | ^ | = help: you might have meant to construct one of the enum's non-tuple variants +note: the enum is defined here + --> $DIR/issue-73427.rs:1:1 + | +LL | / enum A { +LL | | StructWithFields { x: () }, +LL | | TupleWithFields(()), +LL | | Struct {}, +LL | | Tuple(), +LL | | Unit, +LL | | } + | |_^ help: try using one of the enum's variants | LL | let x = A::TupleWithFields(3); @@ -59,6 +132,17 @@ LL | if let A(3) = x { } | ^ | = help: you might have meant to match against one of the enum's non-tuple variants +note: the enum is defined here + --> $DIR/issue-73427.rs:1:1 + | +LL | / enum A { +LL | | StructWithFields { x: () }, +LL | | TupleWithFields(()), +LL | | Struct {}, +LL | | Tuple(), +LL | | Unit, +LL | | } + | |_^ help: try using one of the enum's variants | LL | if let A::TupleWithFields(3) = x { } diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index 77429f800f1a3..807dadf417bf5 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -2,17 +2,57 @@ error[E0423]: expected value, found enum `n::Z` --> $DIR/privacy-enum-ctor.rs:23:9 | LL | n::Z; - | ^^^^ help: try using one of the enum's variants: `m::Z::Unit` + | ^^^^ | - = help: you might have meant to use one of the enum's other variants that have fields +note: the enum is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 + | +LL | / pub(in m) enum Z { +LL | | Fn(u8), +LL | | Struct { +LL | | s: u8, +LL | | }, +LL | | Unit, +LL | | } + | |_________^ +help: you might have meant to use the following enum variant + | +LL | m::Z::Unit; + | ^^^^^^^^^^ +help: the following enum variants are available + | +LL | (m::Z::Fn(/* fields */)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (m::Z::Struct { /* fields */ }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0423]: expected value, found enum `Z` --> $DIR/privacy-enum-ctor.rs:25:9 | LL | Z; - | ^ help: try using one of the enum's variants: `m::Z::Unit` + | ^ + | +note: the enum is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 | - = help: you might have meant to use one of the enum's other variants that have fields +LL | / pub(in m) enum Z { +LL | | Fn(u8), +LL | | Struct { +LL | | s: u8, +LL | | }, +LL | | Unit, +LL | | } + | |_________^ +help: you might have meant to use the following enum variant + | +LL | m::Z::Unit; + | ^^^^^^^^^^ +help: the following enum variants are available + | +LL | (m::Z::Fn(/* fields */)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (m::Z::Struct { /* fields */ }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0423]: expected value, found struct variant `Z::Struct` --> $DIR/privacy-enum-ctor.rs:29:20 @@ -34,11 +74,27 @@ LL | fn f() { LL | let _: E = m::E; | ^^^^ | - = help: you might have meant to use one of the enum's other variants that have fields -help: try using one of the enum's variants +note: the enum is defined here + --> $DIR/privacy-enum-ctor.rs:2:5 + | +LL | / pub enum E { +LL | | Fn(u8), +LL | | Struct { +LL | | s: u8, +LL | | }, +LL | | Unit, +LL | | } + | |_____^ +help: you might have meant to use the following enum variant | LL | let _: E = E::Unit; | ^^^^^^^ +help: the following enum variants are available + | +LL | let _: E = (E::Fn(/* fields */)); + | ^^^^^^^^^^^^^^^^^^^^^ +LL | let _: E = (E::Struct { /* fields */ }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists | LL | let _: E = m::f; @@ -67,11 +123,27 @@ error[E0423]: expected value, found enum `E` LL | let _: E = E; | ^ | - = help: you might have meant to use one of the enum's other variants that have fields -help: try using one of the enum's variants +note: the enum is defined here + --> $DIR/privacy-enum-ctor.rs:2:5 + | +LL | / pub enum E { +LL | | Fn(u8), +LL | | Struct { +LL | | s: u8, +LL | | }, +LL | | Unit, +LL | | } + | |_____^ +help: you might have meant to use the following enum variant | LL | let _: E = E::Unit; | ^^^^^^^ +help: the following enum variants are available + | +LL | let _: E = (E::Fn(/* fields */)); + | ^^^^^^^^^^^^^^^^^^^^^ +LL | let _: E = (E::Struct { /* fields */ }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider importing one of these items instead | LL | use std::f32::consts::E; @@ -112,9 +184,29 @@ error[E0423]: expected value, found enum `m::n::Z` --> $DIR/privacy-enum-ctor.rs:57:16 | LL | let _: Z = m::n::Z; - | ^^^^^^^ help: try using one of the enum's variants: `m::Z::Unit` + | ^^^^^^^ + | +note: the enum is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 + | +LL | / pub(in m) enum Z { +LL | | Fn(u8), +LL | | Struct { +LL | | s: u8, +LL | | }, +LL | | Unit, +LL | | } + | |_________^ +help: you might have meant to use the following enum variant + | +LL | let _: Z = m::Z::Unit; + | ^^^^^^^^^^ +help: the following enum variants are available | - = help: you might have meant to use one of the enum's other variants that have fields +LL | let _: Z = (m::Z::Fn(/* fields */)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _: Z = (m::Z::Struct { /* fields */ }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0412]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:61:12 From f897162f3efc841461adce9510bb627cea9bac45 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 12 Oct 2020 16:52:51 +0100 Subject: [PATCH 08/15] resolve: improve "try using tuple struct" message This commit improves the tuple struct case added in rust-lang/rust#77341 so that the context is mentioned in more of the message. Signed-off-by: David Wood --- .../rustc_resolve/src/late/diagnostics.rs | 22 +++++++++---------- ...issue-43871-enum-instead-of-variant.stderr | 6 ++--- src/test/ui/issues/issue-73427.stderr | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 8ef99f36a04af..c24b383f3b811 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1341,29 +1341,29 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let non_suggestable_variant_count = variants.len() - suggestable_variants.len(); + let source_msg = if source.is_call() { + "to construct" + } else if matches!(source, PathSource::TupleStruct(..)) { + "to match against" + } else { + unreachable!() + }; + if !suggestable_variants.is_empty() { let msg = if non_suggestable_variant_count == 0 && suggestable_variants.len() == 1 { - "try using the enum's variant" + format!("try {} the enum's variant", source_msg) } else { - "try using one of the enum's variants" + format!("try {} one of the enum's variants", source_msg) }; err.span_suggestions( span, - msg, + &msg, suggestable_variants.drain(..), Applicability::MaybeIncorrect, ); } - let source_msg = if source.is_call() { - "to construct" - } else if matches!(source, PathSource::TupleStruct(..)) { - "to match against" - } else { - unreachable!() - }; - // If the enum has no tuple variants.. if non_suggestable_variant_count == variants.len() { err.help(&format!("the enum has no tuple variants {}", source_msg)); diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr index 62a7649e2adf7..bca493e67d543 100644 --- a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr +++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr @@ -2,7 +2,7 @@ error[E0423]: expected function, tuple struct or tuple variant, found enum `Opti --> $DIR/issue-43871-enum-instead-of-variant.rs:19:13 | LL | let x = Option(1); - | ^^^^^^ help: try using one of the enum's variants: `std::option::Option::Some` + | ^^^^^^ help: try to construct one of the enum's variants: `std::option::Option::Some` | = help: you might have meant to construct the enum's non-tuple variant @@ -10,7 +10,7 @@ error[E0532]: expected tuple struct or tuple variant, found enum `Option` --> $DIR/issue-43871-enum-instead-of-variant.rs:21:12 | LL | if let Option(_) = x { - | ^^^^^^ help: try using one of the enum's variants: `std::option::Option::Some` + | ^^^^^^ help: try to match against one of the enum's variants: `std::option::Option::Some` | = help: you might have meant to match against the enum's non-tuple variant @@ -18,7 +18,7 @@ error[E0532]: expected tuple struct or tuple variant, found enum `Example` --> $DIR/issue-43871-enum-instead-of-variant.rs:27:12 | LL | if let Example(_) = y { - | ^^^^^^^ help: try using one of the enum's variants: `Example::Ex` + | ^^^^^^^ help: try to match against one of the enum's variants: `Example::Ex` | = help: you might have meant to match against the enum's non-tuple variant note: the enum is defined here diff --git a/src/test/ui/issues/issue-73427.stderr b/src/test/ui/issues/issue-73427.stderr index 4da5305e6870f..4b5f65b346174 100644 --- a/src/test/ui/issues/issue-73427.stderr +++ b/src/test/ui/issues/issue-73427.stderr @@ -118,7 +118,7 @@ LL | | Tuple(), LL | | Unit, LL | | } | |_^ -help: try using one of the enum's variants +help: try to construct one of the enum's variants | LL | let x = A::TupleWithFields(3); | ^^^^^^^^^^^^^^^^^^ @@ -143,7 +143,7 @@ LL | | Tuple(), LL | | Unit, LL | | } | |_^ -help: try using one of the enum's variants +help: try to match against one of the enum's variants | LL | if let A::TupleWithFields(3) = x { } | ^^^^^^^^^^^^^^^^^^ From 865c30d52ac19481ad7714979ef49c1bd5b1f663 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 15 Oct 2020 15:21:12 -0400 Subject: [PATCH 09/15] Bump backtrace-rs This pulls in https://github.com/rust-lang/backtrace-rs/pull/376, which fixes Miri support for `std::backtrace::Backtrace`. --- library/backtrace | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/backtrace b/library/backtrace index 893fbb23688e9..a6dd47bd588c8 160000 --- a/library/backtrace +++ b/library/backtrace @@ -1 +1 @@ -Subproject commit 893fbb23688e98376e54c26b59432a2966a8cc96 +Subproject commit a6dd47bd588c882e735675a1379d2b61719fa380 From 65835d1059b91fb6458942ea1dc4273990b035e2 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 15 Oct 2020 09:25:30 -0400 Subject: [PATCH 10/15] Deny broken intra-doc links in linkchecker Since rustdoc isn't warning about these links, check for them manually. --- Cargo.lock | 4 ++ .../src/error_codes/E0660.md | 2 +- .../src/error_codes/E0661.md | 2 +- .../src/error_codes/E0662.md | 2 +- .../src/error_codes/E0663.md | 2 +- .../src/error_codes/E0664.md | 2 +- library/core/src/alloc/mod.rs | 12 +--- library/core/src/convert/mod.rs | 1 + library/core/src/iter/traits/double_ended.rs | 3 + library/core/src/iter/traits/iterator.rs | 6 +- library/core/src/option.rs | 1 + library/std/src/ffi/c_str.rs | 3 +- .../src/library-features/default-free-fn.md | 2 + src/tools/linkchecker/Cargo.toml | 4 ++ src/tools/linkchecker/main.rs | 62 +++++++++++++++++++ 15 files changed, 90 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45904a524561b..23c7c4bcb354e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1744,6 +1744,10 @@ dependencies = [ [[package]] name = "linkchecker" version = "0.1.0" +dependencies = [ + "once_cell", + "regex", +] [[package]] name = "linked-hash-map" diff --git a/compiler/rustc_error_codes/src/error_codes/E0660.md b/compiler/rustc_error_codes/src/error_codes/E0660.md index fccd1b96f60db..26d35f2620cb2 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0660.md +++ b/compiler/rustc_error_codes/src/error_codes/E0660.md @@ -9,4 +9,4 @@ llvm_asm!("nop" "nop"); Considering that this would be a long explanation, we instead recommend you take a look at the [`llvm_asm`] chapter of the Unstable book: -[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html +[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0661.md b/compiler/rustc_error_codes/src/error_codes/E0661.md index f1debee7a18f1..0b8ba7fbbedac 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0661.md +++ b/compiler/rustc_error_codes/src/error_codes/E0661.md @@ -10,4 +10,4 @@ llvm_asm!("nop" : "r"(a)); Considering that this would be a long explanation, we instead recommend you take a look at the [`llvm_asm`] chapter of the Unstable book: -[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html +[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0662.md b/compiler/rustc_error_codes/src/error_codes/E0662.md index d4765f078b0e6..8c1bab8d0410d 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0662.md +++ b/compiler/rustc_error_codes/src/error_codes/E0662.md @@ -13,4 +13,4 @@ llvm_asm!("xor %eax, %eax" Considering that this would be a long explanation, we instead recommend you take a look at the [`llvm_asm`] chapter of the Unstable book: -[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html +[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0663.md b/compiler/rustc_error_codes/src/error_codes/E0663.md index d5a85b275db63..53ffd3373a51c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0663.md +++ b/compiler/rustc_error_codes/src/error_codes/E0663.md @@ -13,4 +13,4 @@ llvm_asm!("xor %eax, %eax" Considering that this would be a long explanation, we instead recommend you take a look at the [`llvm_asm`] chapter of the Unstable book: -[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html +[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0664.md b/compiler/rustc_error_codes/src/error_codes/E0664.md index ce9c9491df3d7..f8e72cd330a31 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0664.md +++ b/compiler/rustc_error_codes/src/error_codes/E0664.md @@ -13,4 +13,4 @@ llvm_asm!("mov $$0x200, %eax" Considering that this would be a long explanation, we instead recommend you take a look at the [`llvm_asm`] chapter of the Unstable book: -[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html +[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index 6d09b4f02635b..c61c19cc7d1d1 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -89,13 +89,11 @@ impl fmt::Display for AllocError { pub unsafe trait AllocRef { /// Attempts to allocate a block of memory. /// - /// On success, returns a [`NonNull<[u8]>`] meeting the size and alignment guarantees of `layout`. + /// On success, returns a [`NonNull<[u8]>`][NonNull] meeting the size and alignment guarantees of `layout`. /// /// The returned block may have a larger size than specified by `layout.size()`, and may or may /// not have its contents initialized. /// - /// [`NonNull<[u8]>`]: NonNull - /// /// # Errors /// /// Returning `Err` indicates that either memory is exhausted or `layout` does not meet @@ -146,7 +144,7 @@ pub unsafe trait AllocRef { /// Attempts to extend the memory block. /// - /// Returns a new [`NonNull<[u8]>`] containing a pointer and the actual size of the allocated + /// Returns a new [`NonNull<[u8]>`][NonNull] containing a pointer and the actual size of the allocated /// memory. The pointer is suitable for holding data described by `new_layout`. To accomplish /// this, the allocator may extend the allocation referenced by `ptr` to fit the new layout. /// @@ -158,8 +156,6 @@ pub unsafe trait AllocRef { /// If this method returns `Err`, then ownership of the memory block has not been transferred to /// this allocator, and the contents of the memory block are unaltered. /// - /// [`NonNull<[u8]>`]: NonNull - /// /// # Safety /// /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator. @@ -271,7 +267,7 @@ pub unsafe trait AllocRef { /// Attempts to shrink the memory block. /// - /// Returns a new [`NonNull<[u8]>`] containing a pointer and the actual size of the allocated + /// Returns a new [`NonNull<[u8]>`][NonNull] containing a pointer and the actual size of the allocated /// memory. The pointer is suitable for holding data described by `new_layout`. To accomplish /// this, the allocator may shrink the allocation referenced by `ptr` to fit the new layout. /// @@ -283,8 +279,6 @@ pub unsafe trait AllocRef { /// If this method returns `Err`, then ownership of the memory block has not been transferred to /// this allocator, and the contents of the memory block are unaltered. /// - /// [`NonNull<[u8]>`]: NonNull - /// /// # Safety /// /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator. diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 2bfeb49b5fab7..3f7110b34cc67 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -134,6 +134,7 @@ pub const fn identity(x: T) -> T { /// want to accept all references that can be converted to [`&str`] as an argument. /// Since both [`String`] and [`&str`] implement `AsRef` we can accept both as input argument. /// +/// [`&str`]: primitive@str /// [`Option`]: Option /// [`Result`]: Result /// [`Borrow`]: crate::borrow::Borrow diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 16bee0e2eee18..2253648ac2e04 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -122,6 +122,9 @@ pub trait DoubleEndedIterator: Iterator { /// assert_eq!(iter.advance_back_by(0), Ok(())); /// assert_eq!(iter.advance_back_by(100), Err(1)); // only `&3` was skipped /// ``` + /// + /// [`Ok(())`]: Ok + /// [`Err(k)`]: Err #[inline] #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 813afcc0ec6e4..4af61111128e9 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -289,12 +289,12 @@ pub trait Iterator { /// This method will eagerly skip `n` elements by calling [`next`] up to `n` /// times until [`None`] is encountered. /// - /// `advance_by(n)` will return [`Ok(())`] if the iterator successfully advances by - /// `n` elements, or [`Err(k)`] if [`None`] is encountered, where `k` is the number + /// `advance_by(n)` will return [`Ok(())`][Ok] if the iterator successfully advances by + /// `n` elements, or [`Err(k)`][Err] if [`None`] is encountered, where `k` is the number /// of elements the iterator is advanced by before running out of elements (i.e. the /// length of the iterator). Note that `k` is always less than `n`. /// - /// Calling `advance_by(0)` does not consume any elements and always returns [`Ok(())`]. + /// Calling `advance_by(0)` does not consume any elements and always returns [`Ok(())`][Ok]. /// /// [`next`]: Iterator::next /// diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 9cb20a0afdc6e..825144e5a6fbe 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -687,6 +687,7 @@ impl Option { /// assert_eq!(Some(4).filter(is_even), Some(4)); /// ``` /// + /// [`Some(t)`]: Some #[inline] #[stable(feature = "option_filter", since = "1.27.0")] pub fn filter bool>(self, predicate: P) -> Self { diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index 13021738af139..6df4eb992594f 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -1383,7 +1383,8 @@ impl CStr { /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a /// [`Cow`]`::`[`Owned`]`(`[`String`]`)` with the result. /// - /// [`str`]: prim@str + /// [`str`]: primitive@str + /// [`&str`]: primitive@str /// [`Borrowed`]: Cow::Borrowed /// [`Owned`]: Cow::Owned /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER diff --git a/src/doc/unstable-book/src/library-features/default-free-fn.md b/src/doc/unstable-book/src/library-features/default-free-fn.md index 5dff73a94dd87..d40a27dddf362 100644 --- a/src/doc/unstable-book/src/library-features/default-free-fn.md +++ b/src/doc/unstable-book/src/library-features/default-free-fn.md @@ -10,6 +10,8 @@ Adds a free `default()` function to the `std::default` module. This function just forwards to [`Default::default()`], but may remove repetition of the word "default" from the call site. +[`Default::default()`]: https://doc.rust-lang.org/nightly/std/default/trait.Default.html#tymethod.default + Here is an example: ```rust diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml index 0994cd2066246..e5d870c039dc1 100644 --- a/src/tools/linkchecker/Cargo.toml +++ b/src/tools/linkchecker/Cargo.toml @@ -7,3 +7,7 @@ edition = "2018" [[bin]] name = "linkchecker" path = "main.rs" + +[dependencies] +regex = "1" +once_cell = "1" diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 4fe493a850d48..f213944e0ab67 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -21,6 +21,9 @@ use std::fs; use std::path::{Component, Path, PathBuf}; use std::rc::Rc; +use once_cell::sync::Lazy; +use regex::Regex; + use crate::Redirect::*; // Add linkcheck exceptions here @@ -50,6 +53,44 @@ const LINKCHECK_EXCEPTIONS: &[(&str, &[&str])] = &[ ("alloc/collections/btree_set/struct.BTreeSet.html", &["#insert-and-complex-keys"]), ]; +#[rustfmt::skip] +const INTRA_DOC_LINK_EXCEPTIONS: &[(&str, &[&str])] = &[ + // This will never have links that are not in other pages. + // To avoid repeating the exceptions twice, an empty list means all broken links are allowed. + ("reference/print.html", &[]), + // All the reference 'links' are actually ENBF highlighted as code + ("reference/comments.html", &[ + "/ !", + "* !", + ]), + ("reference/identifiers.html", &[ + "a-z A-Z", + "a-z A-Z 0-9 _", + "a-z A-Z] [a-z A-Z 0-9 _", + ]), + ("reference/tokens.html", &[ + "0-1", + "0-7", + "0-9", + "0-9", + "0-9 a-f A-F", + ]), + ("reference/notation.html", &[ + "b B", + "a-z", + ]), + // This is being used in the sense of 'inclusive range', not a markdown link + ("core/ops/struct.RangeInclusive.html", &["begin, end"]), + ("std/ops/struct.RangeInclusive.html", &["begin, end"]), + ("core/slice/trait.SliceIndex.html", &["begin, end"]), + ("alloc/slice/trait.SliceIndex.html", &["begin, end"]), + ("std/slice/trait.SliceIndex.html", &["begin, end"]), + +]; + +static BROKEN_INTRA_DOC_LINK: Lazy = + Lazy::new(|| Regex::new(r#"\[(.*)\]"#).unwrap()); + macro_rules! t { ($e:expr) => { match $e { @@ -138,6 +179,14 @@ fn walk(cache: &mut Cache, root: &Path, dir: &Path, errors: &mut bool) { } } +fn is_intra_doc_exception(file: &Path, link: &str) -> bool { + if let Some(entry) = INTRA_DOC_LINK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) { + entry.1.is_empty() || entry.1.contains(&link) + } else { + false + } +} + fn is_exception(file: &Path, link: &str) -> bool { if let Some(entry) = LINKCHECK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) { entry.1.contains(&link) @@ -292,6 +341,19 @@ fn check(cache: &mut Cache, root: &Path, file: &Path, errors: &mut bool) -> Opti } } }); + + // Search for intra-doc links that rustdoc didn't warn about + // FIXME(#77199, 77200) Rustdoc should just warn about these directly. + // NOTE: only looks at one line at a time; in practice this should find most links + for (i, line) in contents.lines().enumerate() { + for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) { + if !is_intra_doc_exception(file, &broken_link[1]) { + *errors = true; + print!("{}:{}: broken intra-doc link - ", pretty_file.display(), i + 1); + println!("{}", &broken_link[0]); + } + } + } Some(pretty_file) } From b221819ff7b2d53b25714635dc72d68d732c491e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 15 Oct 2020 20:29:21 -0400 Subject: [PATCH 11/15] Update submodules for link fixes - [rust-embedded](https://github.com/rust-embedded/book/compare/79ab7776929c66db83203397958fa7037d5d9a30...ca8169e69b479f615855d0eece7e318138fcfc00) - [cargo](https://github.com/rust-lang/cargo/compare/12db56cdedbc2c26a9aa18f994c0188cdcc67df5...79b397d72c557eb6444a2ba0dc00a211a226a35a) --- src/doc/embedded-book | 2 +- src/tools/cargo | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/embedded-book b/src/doc/embedded-book index 79ab7776929c6..ca8169e69b479 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit 79ab7776929c66db83203397958fa7037d5d9a30 +Subproject commit ca8169e69b479f615855d0eece7e318138fcfc00 diff --git a/src/tools/cargo b/src/tools/cargo index 12db56cdedbc2..79b397d72c557 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 12db56cdedbc2c26a9aa18f994c0188cdcc67df5 +Subproject commit 79b397d72c557eb6444a2ba0dc00a211a226a35a From 6a32e794c2180a514ad80d3a481300b9afe0b536 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 4 Oct 2020 22:24:14 +0200 Subject: [PATCH 12/15] stabilize union with 'ManuallyDrop' fields and 'impl Drop for Union' --- compiler/rustc_passes/src/stability.rs | 52 +++++++++++-------- compiler/rustc_typeck/src/check/check.rs | 3 +- src/test/ui/did_you_mean/bad-assoc-ty.rs | 1 - src/test/ui/did_you_mean/bad-assoc-ty.stderr | 21 ++------ src/test/ui/drop/dynamic-drop.rs | 2 +- src/test/ui/dropck/dropck-union.rs | 2 - src/test/ui/dropck/dropck-union.stderr | 2 +- .../feature-gate-untagged_unions.rs | 16 ++++-- .../feature-gate-untagged_unions.stderr | 42 ++++----------- .../ui/reject-specialized-drops-8142.stderr | 24 ++++----- src/test/ui/self/self-in-typedefs.rs | 3 -- src/test/ui/transmute/main.rs | 3 -- src/test/ui/transmute/main.stderr | 8 +-- src/test/ui/union/union-align.rs | 3 +- src/test/ui/union/union-copy.rs | 4 +- src/test/ui/union/union-copy.stderr | 6 +-- src/test/ui/union/union-derive-clone.rs | 2 - src/test/ui/union/union-derive-clone.stderr | 4 +- src/test/ui/union/union-derive-eq.rs | 4 +- src/test/ui/union/union-derive-eq.stderr | 2 +- src/test/ui/union/union-derive-rpass.rs | 2 - src/test/ui/union/union-drop-assign.rs | 2 - src/test/ui/union/union-drop.rs | 3 +- src/test/ui/union/union-generic-rpass.rs | 4 +- src/test/ui/union/union-manuallydrop-rpass.rs | 1 - src/test/ui/union/union-nodrop.rs | 2 - src/test/ui/union/union-overwrite.rs | 1 - src/test/ui/union/union-packed.rs | 3 +- src/test/ui/union/union-unsafe.rs | 1 - src/test/ui/union/union-unsafe.stderr | 22 ++++---- 30 files changed, 97 insertions(+), 148 deletions(-) diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 1378b0d57053e..c9497f2a5b2b0 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -13,15 +13,13 @@ use rustc_hir::{Generics, HirId, Item, StructField, TraitRef, Ty, TyKind, Varian use rustc_middle::hir::map::Map; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::middle::stability::{DeprecationEntry, Index}; -use rustc_middle::ty::query::Providers; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{self, query::Providers, TyCtxt}; use rustc_session::lint; use rustc_session::lint::builtin::INEFFECTIVE_UNSTABLE_TRAIT_IMPL; use rustc_session::parse::feature_err; use rustc_session::Session; use rustc_span::symbol::{sym, Symbol}; -use rustc_span::Span; -use rustc_trait_selection::traits::misc::can_type_implement_copy; +use rustc_span::{Span, DUMMY_SP}; use std::cmp::Ordering; use std::mem::replace; @@ -711,27 +709,35 @@ impl Visitor<'tcx> for Checker<'tcx> { // so semi-randomly perform it here in stability.rs hir::ItemKind::Union(..) if !self.tcx.features().untagged_unions => { let def_id = self.tcx.hir().local_def_id(item.hir_id); - let adt_def = self.tcx.adt_def(def_id); let ty = self.tcx.type_of(def_id); + let (adt_def, substs) = match ty.kind() { + ty::Adt(adt_def, substs) => (adt_def, substs), + _ => bug!(), + }; - if adt_def.has_dtor(self.tcx) { - feature_err( - &self.tcx.sess.parse_sess, - sym::untagged_unions, - item.span, - "unions with `Drop` implementations are unstable", - ) - .emit(); - } else { - let param_env = self.tcx.param_env(def_id); - if can_type_implement_copy(self.tcx, param_env, ty).is_err() { - feature_err( - &self.tcx.sess.parse_sess, - sym::untagged_unions, - item.span, - "unions with non-`Copy` fields are unstable", - ) - .emit(); + // Non-`Copy` fields are unstable, except for `ManuallyDrop`. + let param_env = self.tcx.param_env(def_id); + for field in &adt_def.non_enum_variant().fields { + let field_ty = field.ty(self.tcx, substs); + if !field_ty.ty_adt_def().map_or(false, |adt_def| adt_def.is_manually_drop()) + && !field_ty.is_copy_modulo_regions(self.tcx.at(DUMMY_SP), param_env) + { + if field_ty.needs_drop(self.tcx, param_env) { + // Avoid duplicate error: This will error later anyway because fields + // that need drop are not allowed. + self.tcx.sess.delay_span_bug( + item.span, + "union should have been rejected due to potentially dropping field", + ); + } else { + feature_err( + &self.tcx.sess.parse_sess, + sym::untagged_unions, + self.tcx.def_span(field.did), + "unions with non-`Copy` fields other than `ManuallyDrop` are unstable", + ) + .emit(); + } } } } diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index b9a5db478552e..3d8653b4a6a47 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -348,8 +348,7 @@ pub(super) fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) { check_packed(tcx, span, def); } -/// When the `#![feature(untagged_unions)]` gate is active, -/// check that the fields of the `union` does not contain fields that need dropping. +/// Check that the fields of the `union` do not need dropping. pub(super) fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool { let item_type = tcx.type_of(item_def_id); if let ty::Adt(def, substs) = item_type.kind() { diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.rs b/src/test/ui/did_you_mean/bad-assoc-ty.rs index e66b432ede20c..99ebe84cd9d83 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.rs +++ b/src/test/ui/did_you_mean/bad-assoc-ty.rs @@ -68,7 +68,6 @@ enum N where F: Fn() -> _ { union O where F: Fn() -> _ { //~^ ERROR the type placeholder `_` is not allowed within types on item signatures -//~| ERROR unions with non-`Copy` fields are unstable foo: F, } diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index 4835d9ab10723..ebc0883370b7d 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -57,19 +57,6 @@ LL | type J = ty!(u8); | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0658]: unions with non-`Copy` fields are unstable - --> $DIR/bad-assoc-ty.rs:69:1 - | -LL | / union O where F: Fn() -> _ { -LL | | -LL | | -LL | | foo: F, -LL | | } - | |_^ - | - = note: see issue #55149 for more information - = help: add `#![feature(untagged_unions)]` to the crate attributes to enable - error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:1:10 | @@ -215,7 +202,7 @@ LL | union O where F: Fn() -> T { | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/bad-assoc-ty.rs:75:29 + --> $DIR/bad-assoc-ty.rs:74:29 | LL | trait P where F: Fn() -> _ { | ^ not allowed in type signatures @@ -226,7 +213,7 @@ LL | trait P where F: Fn() -> T { | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/bad-assoc-ty.rs:80:38 + --> $DIR/bad-assoc-ty.rs:79:38 | LL | fn foo(_: F) where F: Fn() -> _ {} | ^ not allowed in type signatures @@ -236,7 +223,7 @@ help: use type parameters instead LL | fn foo(_: F) where F: Fn() -> T {} | ^^^ ^ -error: aborting due to 29 previous errors +error: aborting due to 28 previous errors -Some errors have detailed explanations: E0121, E0223, E0658. +Some errors have detailed explanations: E0121, E0223. For more information about an error, try `rustc --explain E0121`. diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index ada61bf0df04c..6d0cd101dbc80 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -1,7 +1,7 @@ // run-pass // ignore-wasm32-bare compiled with panic=abort by default -#![feature(generators, generator_trait, untagged_unions)] +#![feature(generators, generator_trait)] #![feature(bindings_after_at)] #![allow(unused_assignments)] diff --git a/src/test/ui/dropck/dropck-union.rs b/src/test/ui/dropck/dropck-union.rs index ef4d1b360b83c..5a9965db5ed47 100644 --- a/src/test/ui/dropck/dropck-union.rs +++ b/src/test/ui/dropck/dropck-union.rs @@ -1,5 +1,3 @@ -#![feature(untagged_unions)] - use std::cell::Cell; use std::ops::Deref; use std::mem::ManuallyDrop; diff --git a/src/test/ui/dropck/dropck-union.stderr b/src/test/ui/dropck/dropck-union.stderr index 228744326f947..854e29385a81b 100644 --- a/src/test/ui/dropck/dropck-union.stderr +++ b/src/test/ui/dropck/dropck-union.stderr @@ -1,5 +1,5 @@ error[E0597]: `v` does not live long enough - --> $DIR/dropck-union.rs:39:18 + --> $DIR/dropck-union.rs:37:18 | LL | v.0.set(Some(&v)); | ^^ borrowed value does not live long enough diff --git a/src/test/ui/feature-gates/feature-gate-untagged_unions.rs b/src/test/ui/feature-gates/feature-gate-untagged_unions.rs index 9ee0e6f681dcc..f5f9631c3bcf9 100644 --- a/src/test/ui/feature-gates/feature-gate-untagged_unions.rs +++ b/src/test/ui/feature-gates/feature-gate-untagged_unions.rs @@ -1,3 +1,5 @@ +// ignore-tidy-linelength + union U1 { // OK a: u8, } @@ -6,15 +8,23 @@ union U2 { // OK a: T, } -union U3 { //~ ERROR unions with non-`Copy` fields are unstable +union U22 { // OK + a: std::mem::ManuallyDrop, +} + +union U3 { a: String, //~ ERROR unions may not contain fields that need dropping } -union U4 { //~ ERROR unions with non-`Copy` fields are unstable +union U32 { // field that does not drop but is not `Copy`, either -- this is the real feature gate test! + a: std::cell::RefCell, //~ ERROR unions with non-`Copy` fields other than `ManuallyDrop` are unstable +} + +union U4 { a: T, //~ ERROR unions may not contain fields that need dropping } -union U5 { //~ ERROR unions with `Drop` implementations are unstable +union U5 { // Having a drop impl is OK a: u8, } diff --git a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr b/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr index 3a123ea1c9398..ed973871b3f06 100644 --- a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr +++ b/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr @@ -1,61 +1,37 @@ -error[E0658]: unions with non-`Copy` fields are unstable - --> $DIR/feature-gate-untagged_unions.rs:9:1 +error[E0658]: unions with non-`Copy` fields other than `ManuallyDrop` are unstable + --> $DIR/feature-gate-untagged_unions.rs:20:5 | -LL | / union U3 { -LL | | a: String, -LL | | } - | |_^ - | - = note: see issue #55149 for more information - = help: add `#![feature(untagged_unions)]` to the crate attributes to enable - -error[E0658]: unions with non-`Copy` fields are unstable - --> $DIR/feature-gate-untagged_unions.rs:13:1 - | -LL | / union U4 { -LL | | a: T, -LL | | } - | |_^ - | - = note: see issue #55149 for more information - = help: add `#![feature(untagged_unions)]` to the crate attributes to enable - -error[E0658]: unions with `Drop` implementations are unstable - --> $DIR/feature-gate-untagged_unions.rs:17:1 - | -LL | / union U5 { -LL | | a: u8, -LL | | } - | |_^ +LL | a: std::cell::RefCell, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #55149 for more information = help: add `#![feature(untagged_unions)]` to the crate attributes to enable error[E0740]: unions may not contain fields that need dropping - --> $DIR/feature-gate-untagged_unions.rs:10:5 + --> $DIR/feature-gate-untagged_unions.rs:16:5 | LL | a: String, | ^^^^^^^^^ | note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/feature-gate-untagged_unions.rs:10:5 + --> $DIR/feature-gate-untagged_unions.rs:16:5 | LL | a: String, | ^^^^^^^^^ error[E0740]: unions may not contain fields that need dropping - --> $DIR/feature-gate-untagged_unions.rs:14:5 + --> $DIR/feature-gate-untagged_unions.rs:24:5 | LL | a: T, | ^^^^ | note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/feature-gate-untagged_unions.rs:14:5 + --> $DIR/feature-gate-untagged_unions.rs:24:5 | LL | a: T, | ^^^^ -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0658, E0740. For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr index f819faa278995..eac2461753355 100644 --- a/src/test/ui/reject-specialized-drops-8142.stderr +++ b/src/test/ui/reject-specialized-drops-8142.stderr @@ -1,15 +1,3 @@ -error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the union it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:67:21 - | -LL | impl Drop for Union { fn drop(&mut self) { } } // REJECT - | ^^^^^ - | -note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:21:1 - | -LL | union Union { f: T } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0367]: `Drop` impl requires `'adds_bnd: 'al` but the struct it is implemented for does not --> $DIR/reject-specialized-drops-8142.rs:23:20 | @@ -145,6 +133,18 @@ note: the implementor must specify the same requirement LL | struct TupleStruct(T); | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the union it is implemented for does not + --> $DIR/reject-specialized-drops-8142.rs:67:21 + | +LL | impl Drop for Union { fn drop(&mut self) { } } // REJECT + | ^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/reject-specialized-drops-8142.rs:21:1 + | +LL | union Union { f: T } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 11 previous errors Some errors have detailed explanations: E0308, E0366, E0367, E0495. diff --git a/src/test/ui/self/self-in-typedefs.rs b/src/test/ui/self/self-in-typedefs.rs index 3b1eb9e1dfa16..81e557d53a660 100644 --- a/src/test/ui/self/self-in-typedefs.rs +++ b/src/test/ui/self/self-in-typedefs.rs @@ -1,7 +1,4 @@ // build-pass (FIXME(62277): could be check-pass?) - -#![feature(untagged_unions)] - #![allow(dead_code)] use std::mem::ManuallyDrop; diff --git a/src/test/ui/transmute/main.rs b/src/test/ui/transmute/main.rs index ea233a47a78c1..cb46fc5ec467d 100644 --- a/src/test/ui/transmute/main.rs +++ b/src/test/ui/transmute/main.rs @@ -1,9 +1,6 @@ // normalize-stderr-32bit: "`&str` \(64 bits\)" -> "`&str` ($$STR bits)" // normalize-stderr-64bit: "`&str` \(128 bits\)" -> "`&str` ($$STR bits)" - - -#![feature(untagged_unions)] use std::mem::transmute; pub trait TypeConstructor<'a> { diff --git a/src/test/ui/transmute/main.stderr b/src/test/ui/transmute/main.stderr index 4e781318329bf..f48562094a4bc 100644 --- a/src/test/ui/transmute/main.stderr +++ b/src/test/ui/transmute/main.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/main.rs:16:5 + --> $DIR/main.rs:13:5 | LL | transmute(x) | ^^^^^^^^^ @@ -7,7 +7,7 @@ LL | transmute(x) = note: `::T` does not have a fixed size error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/main.rs:20:17 + --> $DIR/main.rs:17:17 | LL | let x: u8 = transmute(10u16); | ^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let x: u8 = transmute(10u16); = note: target type: `u8` (8 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/main.rs:24:17 + --> $DIR/main.rs:21:17 | LL | let x: u8 = transmute("test"); | ^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let x: u8 = transmute("test"); = note: target type: `u8` (8 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/main.rs:29:18 + --> $DIR/main.rs:26:18 | LL | let x: Foo = transmute(10); | ^^^^^^^^^ diff --git a/src/test/ui/union/union-align.rs b/src/test/ui/union/union-align.rs index edd83a5116993..1340ae43cd6af 100644 --- a/src/test/ui/union/union-align.rs +++ b/src/test/ui/union/union-align.rs @@ -1,8 +1,6 @@ // run-pass #![allow(dead_code)] -#![feature(untagged_unions)] - use std::mem::{size_of, size_of_val, align_of, align_of_val}; #[repr(align(16))] @@ -35,6 +33,7 @@ mod hybrid { use std::mem::{size_of, align_of}; #[repr(align(16))] + #[derive(Copy, Clone)] struct S1 { a: u16, b: u8, diff --git a/src/test/ui/union/union-copy.rs b/src/test/ui/union/union-copy.rs index 8318f96940e93..5c3f8d9089819 100644 --- a/src/test/ui/union/union-copy.rs +++ b/src/test/ui/union/union-copy.rs @@ -1,5 +1,3 @@ -#![feature(untagged_unions)] - #[derive(Clone)] union U { a: u8 @@ -7,7 +5,7 @@ union U { #[derive(Clone)] union W { - a: String + a: std::mem::ManuallyDrop } impl Copy for U {} // OK diff --git a/src/test/ui/union/union-copy.stderr b/src/test/ui/union/union-copy.stderr index a875ff660f979..0f47bae7f0fed 100644 --- a/src/test/ui/union/union-copy.stderr +++ b/src/test/ui/union/union-copy.stderr @@ -1,8 +1,8 @@ error[E0204]: the trait `Copy` may not be implemented for this type - --> $DIR/union-copy.rs:14:6 + --> $DIR/union-copy.rs:12:6 | -LL | a: String - | --------- this field does not implement `Copy` +LL | a: std::mem::ManuallyDrop + | --------------------------------- this field does not implement `Copy` ... LL | impl Copy for W {} | ^^^^ diff --git a/src/test/ui/union/union-derive-clone.rs b/src/test/ui/union/union-derive-clone.rs index 8126980604aab..753a9f74d03e4 100644 --- a/src/test/ui/union/union-derive-clone.rs +++ b/src/test/ui/union/union-derive-clone.rs @@ -1,5 +1,3 @@ -#![feature(untagged_unions)] - use std::mem::ManuallyDrop; #[derive(Clone)] //~ ERROR the trait bound `U1: Copy` is not satisfied diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr index 7a59f539c37e7..e18f457a8b6f5 100644 --- a/src/test/ui/union/union-derive-clone.stderr +++ b/src/test/ui/union/union-derive-clone.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `U1: Copy` is not satisfied - --> $DIR/union-derive-clone.rs:5:10 + --> $DIR/union-derive-clone.rs:3:10 | LL | #[derive(Clone)] | ^^^^^ the trait `Copy` is not implemented for `U1` @@ -12,7 +12,7 @@ LL | pub struct AssertParamIsCopy { = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: no method named `clone` found for union `U5` in the current scope - --> $DIR/union-derive-clone.rs:37:15 + --> $DIR/union-derive-clone.rs:35:15 | LL | union U5 { | ----------- diff --git a/src/test/ui/union/union-derive-eq.rs b/src/test/ui/union/union-derive-eq.rs index ac5808e4361eb..e689f8c27d772 100644 --- a/src/test/ui/union/union-derive-eq.rs +++ b/src/test/ui/union/union-derive-eq.rs @@ -1,5 +1,3 @@ -#![feature(untagged_unions)] - #[derive(Eq)] // OK union U1 { a: u8, @@ -7,7 +5,7 @@ union U1 { impl PartialEq for U1 { fn eq(&self, rhs: &Self) -> bool { true } } -#[derive(PartialEq)] +#[derive(PartialEq, Copy, Clone)] struct PartialEqNotEq; #[derive(Eq)] diff --git a/src/test/ui/union/union-derive-eq.stderr b/src/test/ui/union/union-derive-eq.stderr index c4d437c6cdd3a..0591d12d598ba 100644 --- a/src/test/ui/union/union-derive-eq.stderr +++ b/src/test/ui/union/union-derive-eq.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `PartialEqNotEq: Eq` is not satisfied - --> $DIR/union-derive-eq.rs:15:5 + --> $DIR/union-derive-eq.rs:13:5 | LL | a: PartialEqNotEq, | ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq` diff --git a/src/test/ui/union/union-derive-rpass.rs b/src/test/ui/union/union-derive-rpass.rs index b2f7ae679fd68..db18a81c1f665 100644 --- a/src/test/ui/union/union-derive-rpass.rs +++ b/src/test/ui/union/union-derive-rpass.rs @@ -4,8 +4,6 @@ // Some traits can be derived for unions. -#![feature(untagged_unions)] - #[derive( Copy, Clone, diff --git a/src/test/ui/union/union-drop-assign.rs b/src/test/ui/union/union-drop-assign.rs index f1511b0a60180..215666bdd9d98 100644 --- a/src/test/ui/union/union-drop-assign.rs +++ b/src/test/ui/union/union-drop-assign.rs @@ -3,8 +3,6 @@ // Drop works for union itself. -#![feature(untagged_unions)] - use std::mem::ManuallyDrop; struct S; diff --git a/src/test/ui/union/union-drop.rs b/src/test/ui/union/union-drop.rs index 4df3ed502827e..9edf582751152 100644 --- a/src/test/ui/union/union-drop.rs +++ b/src/test/ui/union/union-drop.rs @@ -4,8 +4,7 @@ // Drop works for union itself. -#![feature(untagged_unions)] - +#[derive(Copy, Clone)] struct S; union U { diff --git a/src/test/ui/union/union-generic-rpass.rs b/src/test/ui/union/union-generic-rpass.rs index eb169c516d2a8..69837f31cab27 100644 --- a/src/test/ui/union/union-generic-rpass.rs +++ b/src/test/ui/union/union-generic-rpass.rs @@ -1,8 +1,6 @@ // run-pass #![allow(dead_code)] -#![feature(untagged_unions)] - use std::mem::ManuallyDrop; union MaybeItem { @@ -16,7 +14,7 @@ union U where A: Copy, B: Copy { } unsafe fn union_transmute(a: A) -> B where A: Copy, B: Copy { - U { a: a }.b + U { a }.b } fn main() { diff --git a/src/test/ui/union/union-manuallydrop-rpass.rs b/src/test/ui/union/union-manuallydrop-rpass.rs index a43a505086569..977d12f108602 100644 --- a/src/test/ui/union/union-manuallydrop-rpass.rs +++ b/src/test/ui/union/union-manuallydrop-rpass.rs @@ -1,4 +1,3 @@ -#![feature(untagged_unions)] #![allow(dead_code)] // run-pass diff --git a/src/test/ui/union/union-nodrop.rs b/src/test/ui/union/union-nodrop.rs index 59282bec59b84..bc58c5995cb80 100644 --- a/src/test/ui/union/union-nodrop.rs +++ b/src/test/ui/union/union-nodrop.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(untagged_unions)] - #![allow(dead_code)] use std::mem::needs_drop; diff --git a/src/test/ui/union/union-overwrite.rs b/src/test/ui/union/union-overwrite.rs index 8234beb74a826..399ed9ae458b8 100644 --- a/src/test/ui/union/union-overwrite.rs +++ b/src/test/ui/union/union-overwrite.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(untagged_unions)] #[repr(C)] #[derive(Copy, Clone)] diff --git a/src/test/ui/union/union-packed.rs b/src/test/ui/union/union-packed.rs index ceb35d94656bb..9cde44c06bd47 100644 --- a/src/test/ui/union/union-packed.rs +++ b/src/test/ui/union/union-packed.rs @@ -2,8 +2,6 @@ #![allow(dead_code)] #![allow(non_snake_case)] -#![feature(untagged_unions)] - use std::mem::{size_of, size_of_val, align_of, align_of_val}; struct S { @@ -118,6 +116,7 @@ mod hybrid { use std::mem::{size_of, align_of}; #[repr(packed)] + #[derive(Copy, Clone)] struct S1 { a: u16, b: u8, diff --git a/src/test/ui/union/union-unsafe.rs b/src/test/ui/union/union-unsafe.rs index 8535cbd019ce8..10f0c467560f4 100644 --- a/src/test/ui/union/union-unsafe.rs +++ b/src/test/ui/union/union-unsafe.rs @@ -1,4 +1,3 @@ -#![feature(untagged_unions)] use std::mem::ManuallyDrop; union U1 { diff --git a/src/test/ui/union/union-unsafe.stderr b/src/test/ui/union/union-unsafe.stderr index e020dab63f8f4..b50d9e1750657 100644 --- a/src/test/ui/union/union-unsafe.stderr +++ b/src/test/ui/union/union-unsafe.stderr @@ -1,5 +1,5 @@ error[E0133]: assignment to non-`Copy` union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:22:5 + --> $DIR/union-unsafe.rs:21:5 | LL | u3.a = ManuallyDrop::new(T::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to non-`Copy` union field @@ -7,7 +7,7 @@ LL | u3.a = ManuallyDrop::new(T::default()); = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:23:6 + --> $DIR/union-unsafe.rs:22:6 | LL | *u3.a = T::default(); | ^^^^ access to union field @@ -15,7 +15,7 @@ LL | *u3.a = T::default(); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:29:6 + --> $DIR/union-unsafe.rs:28:6 | LL | *u3.a = T::default(); | ^^^^ access to union field @@ -23,7 +23,7 @@ LL | *u3.a = T::default(); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:37:13 + --> $DIR/union-unsafe.rs:36:13 | LL | let a = u1.a; | ^^^^ access to union field @@ -31,7 +31,7 @@ LL | let a = u1.a; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:40:14 + --> $DIR/union-unsafe.rs:39:14 | LL | let U1 { a } = u1; | ^ access to union field @@ -39,7 +39,7 @@ LL | let U1 { a } = u1; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:41:20 + --> $DIR/union-unsafe.rs:40:20 | LL | if let U1 { a: 12 } = u1 {} | ^^ access to union field @@ -47,7 +47,7 @@ LL | if let U1 { a: 12 } = u1 {} = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: assignment to non-`Copy` union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:45:5 + --> $DIR/union-unsafe.rs:44:5 | LL | u2.a = ManuallyDrop::new(String::from("new")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to non-`Copy` union field @@ -55,7 +55,7 @@ LL | u2.a = ManuallyDrop::new(String::from("new")); = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:46:6 + --> $DIR/union-unsafe.rs:45:6 | LL | *u2.a = String::from("new"); | ^^^^ access to union field @@ -63,7 +63,7 @@ LL | *u2.a = String::from("new"); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:50:6 + --> $DIR/union-unsafe.rs:49:6 | LL | *u3.a = 1; | ^^^^ access to union field @@ -71,7 +71,7 @@ LL | *u3.a = 1; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: assignment to non-`Copy` union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:53:5 + --> $DIR/union-unsafe.rs:52:5 | LL | u3.a = ManuallyDrop::new(String::from("new")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to non-`Copy` union field @@ -79,7 +79,7 @@ LL | u3.a = ManuallyDrop::new(String::from("new")); = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:54:6 + --> $DIR/union-unsafe.rs:53:6 | LL | *u3.a = String::from("new"); | ^^^^ access to union field From defcd7ff47d81f184eb3ba5c1d44bbb9e3658de0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 5 Oct 2020 09:20:39 +0200 Subject: [PATCH 13/15] stop relying on feature(untagged_unions) in stdlib --- library/core/src/lib.rs | 2 +- library/core/src/ptr/mod.rs | 10 ++++++++++ library/std/src/lib.rs | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 97f27566eb0f4..737a95b603b2a 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -131,7 +131,7 @@ #![feature(transparent_unions)] #![feature(unboxed_closures)] #![feature(unsized_locals)] -#![feature(untagged_unions)] +#![cfg_attr(bootstrap, feature(untagged_unions))] #![feature(unwind_attributes)] #![feature(variant_count)] #![feature(tbm_target_feature)] diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 92c4f2ccfe8a0..bca3be56ba5f5 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -229,6 +229,16 @@ pub(crate) struct FatPtr { pub(crate) len: usize, } +// Manual impl needed to avoid `T: Clone` bound. +impl Clone for FatPtr { + fn clone(&self) -> Self { + *self + } +} + +// Manual impl needed to avoid `T: Copy` bound. +impl Copy for FatPtr {} + /// Forms a raw slice from a pointer and a length. /// /// The `len` argument is the number of **elements**, not the number of bytes. diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 5224672adb28b..30e7a7f3c3b10 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -319,7 +319,7 @@ #![feature(unsafe_block_in_unsafe_fn)] #![feature(unsafe_cell_get_mut)] #![feature(unsafe_cell_raw_get)] -#![feature(untagged_unions)] +#![cfg_attr(bootstrap, feature(untagged_unions))] #![feature(unwind_attributes)] #![feature(vec_into_raw_parts)] #![feature(wake_trait)] From a577942a8f398a516a1156be8e3e672cd28edf3d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 16 Oct 2020 15:01:17 +0200 Subject: [PATCH 14/15] Fix sidebar scroll on mobile devices --- src/librustdoc/html/static/main.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 1b3eb2011afdc..67e50bba1f2e0 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2716,10 +2716,6 @@ function defocusSearchBar() { }; } - window.onresize = function() { - hideSidebar(); - }; - if (main) { onEachLazy(main.getElementsByClassName("loading-content"), function(e) { e.remove(); From f7150be6745905b83f88c5397b15233f38d2a8be Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 14 Oct 2020 08:35:32 +0900 Subject: [PATCH 15/15] Suggest minimal subset features in `incomplete_features` lint --- compiler/rustc_lint/src/builtin.rs | 8 ++++++++ src/test/ui/array-slice-vec/match_arr_unknown_len.stderr | 1 + .../ui/associated-types/defaults-specialization.stderr | 1 + src/test/ui/binding/const-param.stderr | 1 + .../coherence-inherited-assoc-ty-cycle-err.stderr | 1 + .../ui/const-generics/defaults/wrong-order.full.stderr | 1 + src/test/ui/const-generics/issues/issue-56445.full.stderr | 1 + .../issues/issue-60818-struct-constructors.full.stderr | 1 + .../ui/const-generics/issues/issue-61336-1.full.stderr | 1 + .../ui/const-generics/issues/issue-61336-2.full.stderr | 1 + src/test/ui/const-generics/issues/issue-61336.full.stderr | 1 + src/test/ui/const-generics/issues/issue-61422.full.stderr | 1 + src/test/ui/const-generics/issues/issue-61432.full.stderr | 1 + src/test/ui/const-generics/issues/issue-61747.full.stderr | 1 + .../ui/const-generics/occurs-check/unify-fixpoint.stderr | 1 + src/test/ui/consts/trait_specialization.stderr | 1 + src/test/ui/error-codes/E0520.stderr | 1 + src/test/ui/error-codes/E0730.stderr | 1 + src/test/ui/error-codes/E0771.stderr | 1 + src/test/ui/hygiene/generic_params.stderr | 1 + src/test/ui/hygiene/issue-61574-const-parameters.stderr | 1 + src/test/ui/impl-trait/equality-rpass.stderr | 1 + src/test/ui/impl-trait/equality.stderr | 1 + src/test/ui/impl-trait/equality2.stderr | 1 + src/test/ui/issues/issue-35376.stderr | 1 + src/test/ui/issues/issue-55380.stderr | 1 + src/test/ui/issues/issue-59508-1.stderr | 1 + .../ui/overlap-doesnt-conflict-with-specialization.stderr | 1 + src/test/ui/parser/assoc-static-semantic-fail.stderr | 1 + src/test/ui/parser/default.stderr | 1 + .../trait-item-with-defaultness-fail-semantic.stderr | 1 + .../ui/polymorphization/const_parameters/closures.stderr | 1 + .../ui/polymorphization/const_parameters/functions.stderr | 1 + src/test/ui/polymorphization/generators.stderr | 1 + .../issue-65035-static-with-parent-generics.stderr | 1 + .../ui/rfc-2497-if-let-chains/disallowed-positions.stderr | 1 + src/test/ui/specialization/assoc-ty-graph-cycle.stderr | 1 + src/test/ui/specialization/cross-crate-defaults.stderr | 1 + .../specialization/deafult-associated-type-bound-1.stderr | 1 + .../specialization/deafult-associated-type-bound-2.stderr | 1 + .../deafult-generic-associated-type-bound.stderr | 1 + .../specialization/defaultimpl/allowed-cross-crate.stderr | 1 + .../ui/specialization/defaultimpl/out-of-order.stderr | 1 + .../specialization/defaultimpl/overlap-projection.stderr | 1 + src/test/ui/specialization/defaultimpl/projection.stderr | 1 + .../defaultimpl/specialization-no-default.stderr | 1 + ...specialization-trait-item-not-implemented-rpass.stderr | 1 + .../specialization-trait-item-not-implemented.stderr | 1 + .../specialization-trait-not-implemented.stderr | 1 + .../defaultimpl/specialization-wfcheck.stderr | 1 + src/test/ui/specialization/defaultimpl/validation.stderr | 1 + src/test/ui/specialization/issue-36804.stderr | 1 + src/test/ui/specialization/issue-38091-2.stderr | 1 + src/test/ui/specialization/issue-38091.stderr | 1 + src/test/ui/specialization/issue-39448.stderr | 1 + src/test/ui/specialization/issue-39618.stderr | 1 + src/test/ui/specialization/issue-50452.stderr | 1 + src/test/ui/specialization/issue-52050.stderr | 1 + src/test/ui/specialization/issue-63716-parse-async.stderr | 1 + src/test/ui/specialization/issue-70442.stderr | 1 + src/test/ui/specialization/non-defaulted-item-fail.stderr | 1 + .../specialization-allowed-cross-crate.stderr | 1 + .../ui/specialization/specialization-assoc-fns.stderr | 1 + src/test/ui/specialization/specialization-basics.stderr | 1 + .../ui/specialization/specialization-cross-crate.stderr | 1 + .../specialization/specialization-default-methods.stderr | 1 + .../specialization-default-projection.stderr | 1 + .../ui/specialization/specialization-default-types.stderr | 1 + .../ui/specialization/specialization-no-default.stderr | 1 + .../ui/specialization/specialization-on-projection.stderr | 1 + .../ui/specialization/specialization-out-of-order.stderr | 1 + .../specialization/specialization-overlap-negative.stderr | 1 + .../specialization-overlap-projection.stderr | 1 + src/test/ui/specialization/specialization-overlap.stderr | 1 + src/test/ui/specialization/specialization-polarity.stderr | 1 + .../specialization/specialization-projection-alias.stderr | 1 + .../ui/specialization/specialization-projection.stderr | 1 + .../ui/specialization/specialization-super-traits.stderr | 1 + ...ialization-translate-projections-with-lifetimes.stderr | 1 + ...pecialization-translate-projections-with-params.stderr | 1 + .../specialization-translate-projections.stderr | 1 + .../traits/negative-impls/negative-default-impls.stderr | 1 + .../negative-impls/negative-specializes-negative.stderr | 1 + .../negative-specializes-positive-item.stderr | 1 + .../negative-impls/negative-specializes-positive.stderr | 1 + .../negative-impls/positive-specializes-negative.stderr | 1 + src/test/ui/transmute-specialization.stderr | 1 + src/test/ui/type-alias-impl-trait/assoc-type-const.stderr | 1 + 88 files changed, 95 insertions(+) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index abd899e8db4d3..a7db9199665ee 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2288,12 +2288,20 @@ impl EarlyLintPass for IncompleteFeatures { n, n, )); } + if HAS_MIN_FEATURES.contains(&name) { + builder.help(&format!( + "consider using `min_{}` instead, which is more stable and complete", + name, + )); + } builder.emit(); }) }); } } +const HAS_MIN_FEATURES: &[Symbol] = &[sym::const_generics, sym::specialization]; + declare_lint! { /// The `invalid_value` lint detects creating a value that is not valid, /// such as a NULL reference. diff --git a/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr index 0ad05b3adeb88..7c1a92c79d973 100644 --- a/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr +++ b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr @@ -6,6 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error[E0308]: mismatched types --> $DIR/match_arr_unknown_len.rs:6:9 diff --git a/src/test/ui/associated-types/defaults-specialization.stderr b/src/test/ui/associated-types/defaults-specialization.stderr index 09a8c8f8a88a2..920f8322813fe 100644 --- a/src/test/ui/associated-types/defaults-specialization.stderr +++ b/src/test/ui/associated-types/defaults-specialization.stderr @@ -6,6 +6,7 @@ LL | #![feature(associated_type_defaults, specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0053]: method `make` has an incompatible type for trait --> $DIR/defaults-specialization.rs:19:18 diff --git a/src/test/ui/binding/const-param.stderr b/src/test/ui/binding/const-param.stderr index 316fac6232548..d3d06a2d834fc 100644 --- a/src/test/ui/binding/const-param.stderr +++ b/src/test/ui/binding/const-param.stderr @@ -6,6 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error[E0158]: const parameters cannot be referenced in patterns --> $DIR/const-param.rs:7:9 diff --git a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr index 7e140480b77d4..f3edf1c350f50 100644 --- a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr +++ b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0391]: cycle detected when building specialization graph of trait `Trait` --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1 diff --git a/src/test/ui/const-generics/defaults/wrong-order.full.stderr b/src/test/ui/const-generics/defaults/wrong-order.full.stderr index c51028d5b2001..99f46309bf6ff 100644 --- a/src/test/ui/const-generics/defaults/wrong-order.full.stderr +++ b/src/test/ui/const-generics/defaults/wrong-order.full.stderr @@ -14,6 +14,7 @@ LL | #![cfg_attr(full, feature(const_generics))] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/const-generics/issues/issue-56445.full.stderr b/src/test/ui/const-generics/issues/issue-56445.full.stderr index d853ec5015ed2..50e9141855112 100644 --- a/src/test/ui/const-generics/issues/issue-56445.full.stderr +++ b/src/test/ui/const-generics/issues/issue-56445.full.stderr @@ -6,6 +6,7 @@ LL | #![cfg_attr(full, feature(const_generics))] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error[E0771]: use of non-static lifetime `'a` in const generic --> $DIR/issue-56445.rs:9:26 diff --git a/src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr b/src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr index c03b7252a3c85..cc014ea429d5c 100644 --- a/src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr +++ b/src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr @@ -6,6 +6,7 @@ LL | #![cfg_attr(full, feature(const_generics))] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/const-generics/issues/issue-61336-1.full.stderr b/src/test/ui/const-generics/issues/issue-61336-1.full.stderr index f18728eabbb43..3a9f819a6262c 100644 --- a/src/test/ui/const-generics/issues/issue-61336-1.full.stderr +++ b/src/test/ui/const-generics/issues/issue-61336-1.full.stderr @@ -6,6 +6,7 @@ LL | #![cfg_attr(full, feature(const_generics))] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/const-generics/issues/issue-61336-2.full.stderr b/src/test/ui/const-generics/issues/issue-61336-2.full.stderr index ef6e60084a5f0..883ebbef3e80d 100644 --- a/src/test/ui/const-generics/issues/issue-61336-2.full.stderr +++ b/src/test/ui/const-generics/issues/issue-61336-2.full.stderr @@ -6,6 +6,7 @@ LL | #![cfg_attr(full, feature(const_generics))] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error[E0277]: the trait bound `T: Copy` is not satisfied --> $DIR/issue-61336-2.rs:10:5 diff --git a/src/test/ui/const-generics/issues/issue-61336.full.stderr b/src/test/ui/const-generics/issues/issue-61336.full.stderr index bdfdffd941d20..3863da8da0548 100644 --- a/src/test/ui/const-generics/issues/issue-61336.full.stderr +++ b/src/test/ui/const-generics/issues/issue-61336.full.stderr @@ -6,6 +6,7 @@ LL | #![cfg_attr(full, feature(const_generics))] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error[E0277]: the trait bound `T: Copy` is not satisfied --> $DIR/issue-61336.rs:10:5 diff --git a/src/test/ui/const-generics/issues/issue-61422.full.stderr b/src/test/ui/const-generics/issues/issue-61422.full.stderr index ac6c378295d31..294378a66901a 100644 --- a/src/test/ui/const-generics/issues/issue-61422.full.stderr +++ b/src/test/ui/const-generics/issues/issue-61422.full.stderr @@ -6,6 +6,7 @@ LL | #![cfg_attr(full, feature(const_generics))] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/const-generics/issues/issue-61432.full.stderr b/src/test/ui/const-generics/issues/issue-61432.full.stderr index 82b36de45a2aa..eec1b20254ed7 100644 --- a/src/test/ui/const-generics/issues/issue-61432.full.stderr +++ b/src/test/ui/const-generics/issues/issue-61432.full.stderr @@ -6,6 +6,7 @@ LL | #![cfg_attr(full, feature(const_generics))] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/const-generics/issues/issue-61747.full.stderr b/src/test/ui/const-generics/issues/issue-61747.full.stderr index 3ccce5675fcba..3a266c8e97422 100644 --- a/src/test/ui/const-generics/issues/issue-61747.full.stderr +++ b/src/test/ui/const-generics/issues/issue-61747.full.stderr @@ -6,6 +6,7 @@ LL | #![cfg_attr(full, feature(const_generics))] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error: constant expression depends on a generic parameter --> $DIR/issue-61747.rs:8:23 diff --git a/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr b/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr index 671f1103dccad..8a1462c59e810 100644 --- a/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr +++ b/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr @@ -6,6 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error: constant expression depends on a generic parameter --> $DIR/unify-fixpoint.rs:9:32 diff --git a/src/test/ui/consts/trait_specialization.stderr b/src/test/ui/consts/trait_specialization.stderr index 03da7d512e592..e80821cf46a4a 100644 --- a/src/test/ui/consts/trait_specialization.stderr +++ b/src/test/ui/consts/trait_specialization.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/error-codes/E0520.stderr b/src/test/ui/error-codes/E0520.stderr index 1041ccee93704..be7b95465a5f7 100644 --- a/src/test/ui/error-codes/E0520.stderr +++ b/src/test/ui/error-codes/E0520.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0520]: `fly` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/E0520.rs:17:5 diff --git a/src/test/ui/error-codes/E0730.stderr b/src/test/ui/error-codes/E0730.stderr index f915f6edef52b..356e4f36042ae 100644 --- a/src/test/ui/error-codes/E0730.stderr +++ b/src/test/ui/error-codes/E0730.stderr @@ -6,6 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error[E0730]: cannot pattern-match on an array without a fixed length --> $DIR/E0730.rs:6:9 diff --git a/src/test/ui/error-codes/E0771.stderr b/src/test/ui/error-codes/E0771.stderr index 60220be6b57ba..b184b59981701 100644 --- a/src/test/ui/error-codes/E0771.stderr +++ b/src/test/ui/error-codes/E0771.stderr @@ -6,6 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error[E0771]: use of non-static lifetime `'a` in const generic --> $DIR/E0771.rs:4:41 diff --git a/src/test/ui/hygiene/generic_params.stderr b/src/test/ui/hygiene/generic_params.stderr index 4ca6d1998353f..6de36deb59764 100644 --- a/src/test/ui/hygiene/generic_params.stderr +++ b/src/test/ui/hygiene/generic_params.stderr @@ -6,6 +6,7 @@ LL | #![feature(decl_macro, rustc_attrs, const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/hygiene/issue-61574-const-parameters.stderr b/src/test/ui/hygiene/issue-61574-const-parameters.stderr index b351b8b73a0e5..3f85383eb33fa 100644 --- a/src/test/ui/hygiene/issue-61574-const-parameters.stderr +++ b/src/test/ui/hygiene/issue-61574-const-parameters.stderr @@ -6,6 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/impl-trait/equality-rpass.stderr b/src/test/ui/impl-trait/equality-rpass.stderr index 1abf05dca8270..11eeceba0eed9 100644 --- a/src/test/ui/impl-trait/equality-rpass.stderr +++ b/src/test/ui/impl-trait/equality-rpass.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index cdaa61ac323dd..536a4726c6de2 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0308]: mismatched types --> $DIR/equality.rs:15:5 diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr index 1780931efc541..1443b76048b32 100644 --- a/src/test/ui/impl-trait/equality2.stderr +++ b/src/test/ui/impl-trait/equality2.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0308]: mismatched types --> $DIR/equality2.rs:25:18 diff --git a/src/test/ui/issues/issue-35376.stderr b/src/test/ui/issues/issue-35376.stderr index 06c31f3bae062..835277d408ef2 100644 --- a/src/test/ui/issues/issue-35376.stderr +++ b/src/test/ui/issues/issue-35376.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/issues/issue-55380.stderr b/src/test/ui/issues/issue-55380.stderr index 451beebd1061e..65e94d7967075 100644 --- a/src/test/ui/issues/issue-55380.stderr +++ b/src/test/ui/issues/issue-55380.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/issues/issue-59508-1.stderr b/src/test/ui/issues/issue-59508-1.stderr index 5e97339f148c5..2a4ccda892919 100644 --- a/src/test/ui/issues/issue-59508-1.stderr +++ b/src/test/ui/issues/issue-59508-1.stderr @@ -12,6 +12,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/overlap-doesnt-conflict-with-specialization.stderr b/src/test/ui/overlap-doesnt-conflict-with-specialization.stderr index 16df31ba2a88b..fca98662708db 100644 --- a/src/test/ui/overlap-doesnt-conflict-with-specialization.stderr +++ b/src/test/ui/overlap-doesnt-conflict-with-specialization.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/parser/assoc-static-semantic-fail.stderr b/src/test/ui/parser/assoc-static-semantic-fail.stderr index bc3054c3e3062..7ae092cee6723 100644 --- a/src/test/ui/parser/assoc-static-semantic-fail.stderr +++ b/src/test/ui/parser/assoc-static-semantic-fail.stderr @@ -170,6 +170,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error: aborting due to 24 previous errors; 1 warning emitted diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr index dea35666f37b5..5b763ae72f5ee 100644 --- a/src/test/ui/parser/default.stderr +++ b/src/test/ui/parser/default.stderr @@ -31,6 +31,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0046]: not all trait items implemented, missing: `foo` --> $DIR/default.rs:22:1 diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr index e8ff93f63237d..cdc9ee8d9e7c9 100644 --- a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr +++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr @@ -54,6 +54,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error: aborting due to 6 previous errors; 1 warning emitted diff --git a/src/test/ui/polymorphization/const_parameters/closures.stderr b/src/test/ui/polymorphization/const_parameters/closures.stderr index 266b6e62afd0b..63335586b765c 100644 --- a/src/test/ui/polymorphization/const_parameters/closures.stderr +++ b/src/test/ui/polymorphization/const_parameters/closures.stderr @@ -6,6 +6,7 @@ LL | #![feature(const_generics, rustc_attrs)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error: item has unused generic parameters --> $DIR/closures.rs:19:19 diff --git a/src/test/ui/polymorphization/const_parameters/functions.stderr b/src/test/ui/polymorphization/const_parameters/functions.stderr index e379e32c1fceb..c976a5b62aa30 100644 --- a/src/test/ui/polymorphization/const_parameters/functions.stderr +++ b/src/test/ui/polymorphization/const_parameters/functions.stderr @@ -6,6 +6,7 @@ LL | #![feature(const_generics, rustc_attrs)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error: item has unused generic parameters --> $DIR/functions.rs:15:8 diff --git a/src/test/ui/polymorphization/generators.stderr b/src/test/ui/polymorphization/generators.stderr index c59055ba9d654..b2b32db045d6a 100644 --- a/src/test/ui/polymorphization/generators.stderr +++ b/src/test/ui/polymorphization/generators.stderr @@ -6,6 +6,7 @@ LL | #![feature(const_generics, generators, generator_trait, rustc_attrs)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error: item has unused generic parameters --> $DIR/generators.rs:36:5 diff --git a/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr b/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr index 7f8151db06f5b..5de8eb215821a 100644 --- a/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr +++ b/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr @@ -48,6 +48,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete error: aborting due to 5 previous errors; 1 warning emitted diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr index d38a3aba46fd3..bd39650702c7c 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -507,6 +507,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete warning: the feature `let_chains` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/disallowed-positions.rs:22:12 diff --git a/src/test/ui/specialization/assoc-ty-graph-cycle.stderr b/src/test/ui/specialization/assoc-ty-graph-cycle.stderr index 250f48f8e5932..17da34caa70d7 100644 --- a/src/test/ui/specialization/assoc-ty-graph-cycle.stderr +++ b/src/test/ui/specialization/assoc-ty-graph-cycle.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/cross-crate-defaults.stderr b/src/test/ui/specialization/cross-crate-defaults.stderr index f18bc99d73916..e368c2e73b6a9 100644 --- a/src/test/ui/specialization/cross-crate-defaults.stderr +++ b/src/test/ui/specialization/cross-crate-defaults.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/deafult-associated-type-bound-1.stderr b/src/test/ui/specialization/deafult-associated-type-bound-1.stderr index 337972ea2b793..4ca3d83119839 100644 --- a/src/test/ui/specialization/deafult-associated-type-bound-1.stderr +++ b/src/test/ui/specialization/deafult-associated-type-bound-1.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0277]: the trait bound `str: Clone` is not satisfied --> $DIR/deafult-associated-type-bound-1.rs:19:5 diff --git a/src/test/ui/specialization/deafult-associated-type-bound-2.stderr b/src/test/ui/specialization/deafult-associated-type-bound-2.stderr index 8c9da81d277ef..2bc14dbe3b2e7 100644 --- a/src/test/ui/specialization/deafult-associated-type-bound-2.stderr +++ b/src/test/ui/specialization/deafult-associated-type-bound-2.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0277]: can't compare `&'static B` with `B` --> $DIR/deafult-associated-type-bound-2.rs:16:5 diff --git a/src/test/ui/specialization/deafult-generic-associated-type-bound.stderr b/src/test/ui/specialization/deafult-generic-associated-type-bound.stderr index f145b90f216ab..b5a1877ea1931 100644 --- a/src/test/ui/specialization/deafult-generic-associated-type-bound.stderr +++ b/src/test/ui/specialization/deafult-generic-associated-type-bound.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/deafult-generic-associated-type-bound.rs:4:12 diff --git a/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr b/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr index 1b50329719d01..d8b9c48c72e92 100644 --- a/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr +++ b/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/defaultimpl/out-of-order.stderr b/src/test/ui/specialization/defaultimpl/out-of-order.stderr index deae021a8914d..9ca915686e84f 100644 --- a/src/test/ui/specialization/defaultimpl/out-of-order.stderr +++ b/src/test/ui/specialization/defaultimpl/out-of-order.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/defaultimpl/overlap-projection.stderr b/src/test/ui/specialization/defaultimpl/overlap-projection.stderr index 46899ca995490..31d0e6e38824b 100644 --- a/src/test/ui/specialization/defaultimpl/overlap-projection.stderr +++ b/src/test/ui/specialization/defaultimpl/overlap-projection.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/defaultimpl/projection.stderr b/src/test/ui/specialization/defaultimpl/projection.stderr index 8629c6c52d4a7..2d5c80d05f019 100644 --- a/src/test/ui/specialization/defaultimpl/projection.stderr +++ b/src/test/ui/specialization/defaultimpl/projection.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr b/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr index 7958eddbeba25..3f1a5495e212f 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/specialization-no-default.rs:20:5 diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr index dc377dd10c868..163c93550fb4d 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr index 9d1eca1d6af76..250f0017bea27 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0046]: not all trait items implemented, missing: `foo_two` --> $DIR/specialization-trait-item-not-implemented.rs:18:1 diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr index 6b8e559bc3634..fb623c97f4209 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0599]: no method named `foo_one` found for struct `MyStruct` in the current scope --> $DIR/specialization-trait-not-implemented.rs:22:29 diff --git a/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr b/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr index dcac310ed065e..57b90c457cb77 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0277]: the trait bound `U: Eq` is not satisfied --> $DIR/specialization-wfcheck.rs:7:17 diff --git a/src/test/ui/specialization/defaultimpl/validation.stderr b/src/test/ui/specialization/defaultimpl/validation.stderr index 2449849725f38..cbf0cef5e7462 100644 --- a/src/test/ui/specialization/defaultimpl/validation.stderr +++ b/src/test/ui/specialization/defaultimpl/validation.stderr @@ -16,6 +16,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error: impls of auto traits cannot be default --> $DIR/validation.rs:9:21 diff --git a/src/test/ui/specialization/issue-36804.stderr b/src/test/ui/specialization/issue-36804.stderr index 744d88204247b..783a38e6bdc00 100644 --- a/src/test/ui/specialization/issue-36804.stderr +++ b/src/test/ui/specialization/issue-36804.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/issue-38091-2.stderr b/src/test/ui/specialization/issue-38091-2.stderr index a314c26ad147d..bd5ed498d92ca 100644 --- a/src/test/ui/specialization/issue-38091-2.stderr +++ b/src/test/ui/specialization/issue-38091-2.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0275]: overflow evaluating the requirement `i32: Check` | diff --git a/src/test/ui/specialization/issue-38091.stderr b/src/test/ui/specialization/issue-38091.stderr index 6be0f26849f90..97e5775ab54ee 100644 --- a/src/test/ui/specialization/issue-38091.stderr +++ b/src/test/ui/specialization/issue-38091.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0277]: the trait bound `(): Valid` is not satisfied --> $DIR/issue-38091.rs:12:5 diff --git a/src/test/ui/specialization/issue-39448.stderr b/src/test/ui/specialization/issue-39448.stderr index f3bb69b8f712a..98e49b1bab3b7 100644 --- a/src/test/ui/specialization/issue-39448.stderr +++ b/src/test/ui/specialization/issue-39448.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0275]: overflow evaluating the requirement `T: FromA` --> $DIR/issue-39448.rs:45:13 diff --git a/src/test/ui/specialization/issue-39618.stderr b/src/test/ui/specialization/issue-39618.stderr index d40d17d8f71ca..77a45806edbab 100644 --- a/src/test/ui/specialization/issue-39618.stderr +++ b/src/test/ui/specialization/issue-39618.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/issue-50452.stderr b/src/test/ui/specialization/issue-50452.stderr index c01817e0b2793..2f05c41346f90 100644 --- a/src/test/ui/specialization/issue-50452.stderr +++ b/src/test/ui/specialization/issue-50452.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/issue-52050.stderr b/src/test/ui/specialization/issue-52050.stderr index a7564ced055d5..27070f8e4a1ca 100644 --- a/src/test/ui/specialization/issue-52050.stderr +++ b/src/test/ui/specialization/issue-52050.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0119]: conflicting implementations of trait `IntoPyDictPointer` for type `()`: --> $DIR/issue-52050.rs:28:1 diff --git a/src/test/ui/specialization/issue-63716-parse-async.stderr b/src/test/ui/specialization/issue-63716-parse-async.stderr index 43620e1ba51e1..cde17872d6bbe 100644 --- a/src/test/ui/specialization/issue-63716-parse-async.stderr +++ b/src/test/ui/specialization/issue-63716-parse-async.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/issue-70442.stderr b/src/test/ui/specialization/issue-70442.stderr index f71e4c7dd1cef..5ee82e9915b6a 100644 --- a/src/test/ui/specialization/issue-70442.stderr +++ b/src/test/ui/specialization/issue-70442.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/non-defaulted-item-fail.stderr b/src/test/ui/specialization/non-defaulted-item-fail.stderr index eae045b92c04d..85ccbd809b02d 100644 --- a/src/test/ui/specialization/non-defaulted-item-fail.stderr +++ b/src/test/ui/specialization/non-defaulted-item-fail.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization, associated_type_defaults)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0520]: `Ty` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/non-defaulted-item-fail.rs:30:5 diff --git a/src/test/ui/specialization/specialization-allowed-cross-crate.stderr b/src/test/ui/specialization/specialization-allowed-cross-crate.stderr index 7d087545725be..9605bd0893514 100644 --- a/src/test/ui/specialization/specialization-allowed-cross-crate.stderr +++ b/src/test/ui/specialization/specialization-allowed-cross-crate.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-assoc-fns.stderr b/src/test/ui/specialization/specialization-assoc-fns.stderr index b12738604ea83..a7c0661a825dc 100644 --- a/src/test/ui/specialization/specialization-assoc-fns.stderr +++ b/src/test/ui/specialization/specialization-assoc-fns.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-basics.stderr b/src/test/ui/specialization/specialization-basics.stderr index ad00cd81df13c..afb2af3803f1d 100644 --- a/src/test/ui/specialization/specialization-basics.stderr +++ b/src/test/ui/specialization/specialization-basics.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-cross-crate.stderr b/src/test/ui/specialization/specialization-cross-crate.stderr index 7481eed796d96..c69130c0aef7b 100644 --- a/src/test/ui/specialization/specialization-cross-crate.stderr +++ b/src/test/ui/specialization/specialization-cross-crate.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-default-methods.stderr b/src/test/ui/specialization/specialization-default-methods.stderr index 4fa19adad066e..ef6365ed31f86 100644 --- a/src/test/ui/specialization/specialization-default-methods.stderr +++ b/src/test/ui/specialization/specialization-default-methods.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-default-projection.stderr b/src/test/ui/specialization/specialization-default-projection.stderr index 456eb6d5ca553..445bc1646f04e 100644 --- a/src/test/ui/specialization/specialization-default-projection.stderr +++ b/src/test/ui/specialization/specialization-default-projection.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:21:5 diff --git a/src/test/ui/specialization/specialization-default-types.stderr b/src/test/ui/specialization/specialization-default-types.stderr index 5acfb53e20653..5ba38facee0c0 100644 --- a/src/test/ui/specialization/specialization-default-types.stderr +++ b/src/test/ui/specialization/specialization-default-types.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:15:9 diff --git a/src/test/ui/specialization/specialization-no-default.stderr b/src/test/ui/specialization/specialization-no-default.stderr index bb8b2a6c98e09..711c1fda1499d 100644 --- a/src/test/ui/specialization/specialization-no-default.stderr +++ b/src/test/ui/specialization/specialization-no-default.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/specialization-no-default.rs:20:5 diff --git a/src/test/ui/specialization/specialization-on-projection.stderr b/src/test/ui/specialization/specialization-on-projection.stderr index d91668d10c5f3..d051ffe0a02c6 100644 --- a/src/test/ui/specialization/specialization-on-projection.stderr +++ b/src/test/ui/specialization/specialization-on-projection.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-out-of-order.stderr b/src/test/ui/specialization/specialization-out-of-order.stderr index a17f9f11a3f31..785ec29239b20 100644 --- a/src/test/ui/specialization/specialization-out-of-order.stderr +++ b/src/test/ui/specialization/specialization-out-of-order.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-overlap-negative.stderr b/src/test/ui/specialization/specialization-overlap-negative.stderr index 6141174ba8c03..552b04a601930 100644 --- a/src/test/ui/specialization/specialization-overlap-negative.stderr +++ b/src/test/ui/specialization/specialization-overlap-negative.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`: --> $DIR/specialization-overlap-negative.rs:9:1 diff --git a/src/test/ui/specialization/specialization-overlap-projection.stderr b/src/test/ui/specialization/specialization-overlap-projection.stderr index 6f1a594bacb3a..c92db73074d4f 100644 --- a/src/test/ui/specialization/specialization-overlap-projection.stderr +++ b/src/test/ui/specialization/specialization-overlap-projection.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-overlap.stderr b/src/test/ui/specialization/specialization-overlap.stderr index cf0f186a18337..7e5c96ac1c884 100644 --- a/src/test/ui/specialization/specialization-overlap.stderr +++ b/src/test/ui/specialization/specialization-overlap.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0119]: conflicting implementations of trait `Foo` for type `std::vec::Vec<_>`: --> $DIR/specialization-overlap.rs:5:1 diff --git a/src/test/ui/specialization/specialization-polarity.stderr b/src/test/ui/specialization/specialization-polarity.stderr index c44af22b8e63b..be013552f5d5f 100644 --- a/src/test/ui/specialization/specialization-polarity.stderr +++ b/src/test/ui/specialization/specialization-polarity.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0751]: found both positive and negative implementation of trait `Foo` for type `u8`: --> $DIR/specialization-polarity.rs:10:1 diff --git a/src/test/ui/specialization/specialization-projection-alias.stderr b/src/test/ui/specialization/specialization-projection-alias.stderr index 0c3659a8f7a06..6d2bca5d2df8c 100644 --- a/src/test/ui/specialization/specialization-projection-alias.stderr +++ b/src/test/ui/specialization/specialization-projection-alias.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-projection.stderr b/src/test/ui/specialization/specialization-projection.stderr index c5c86f5108e6e..0f1ecf5e379c2 100644 --- a/src/test/ui/specialization/specialization-projection.stderr +++ b/src/test/ui/specialization/specialization-projection.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-super-traits.stderr b/src/test/ui/specialization/specialization-super-traits.stderr index 05bdfd40136a4..165703d636574 100644 --- a/src/test/ui/specialization/specialization-super-traits.stderr +++ b/src/test/ui/specialization/specialization-super-traits.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr index 6284dd8f3f7d7..d30f7af2cbdce 100644 --- a/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr +++ b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-translate-projections-with-params.stderr b/src/test/ui/specialization/specialization-translate-projections-with-params.stderr index b17794173c570..1762248f6956b 100644 --- a/src/test/ui/specialization/specialization-translate-projections-with-params.stderr +++ b/src/test/ui/specialization/specialization-translate-projections-with-params.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-translate-projections.stderr b/src/test/ui/specialization/specialization-translate-projections.stderr index fbb28e6064088..94a0e79dd5663 100644 --- a/src/test/ui/specialization/specialization-translate-projections.stderr +++ b/src/test/ui/specialization/specialization-translate-projections.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/traits/negative-impls/negative-default-impls.stderr b/src/test/ui/traits/negative-impls/negative-default-impls.stderr index 50e74373b53bb..ceb86559d85e2 100644 --- a/src/test/ui/traits/negative-impls/negative-default-impls.stderr +++ b/src/test/ui/traits/negative-impls/negative-default-impls.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0750]: negative impls cannot be default impls --> $DIR/negative-default-impls.rs:9:1 diff --git a/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr b/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr index 8b536de378630..9a846143d3d30 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr +++ b/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr index 89ef15e89ac96..77b4373a273b7 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr +++ b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/negative-specializes-positive-item.rs:11:1 diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr b/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr index e45d5a251ab26..e5dc81b3eb75a 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr +++ b/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/negative-specializes-positive.rs:7:1 diff --git a/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr b/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr index 49c16d474040e..c091bc81da340 100644 --- a/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr +++ b/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/positive-specializes-negative.rs:7:1 diff --git a/src/test/ui/transmute-specialization.stderr b/src/test/ui/transmute-specialization.stderr index 02315051d30ec..a0ea72415a189 100644 --- a/src/test/ui/transmute-specialization.stderr +++ b/src/test/ui/transmute-specialization.stderr @@ -6,6 +6,7 @@ LL | #![feature(specialization)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete warning: 1 warning emitted diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr b/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr index e0c1b02386127..c5b22f0026de4 100644 --- a/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr +++ b/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr @@ -6,6 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information + = help: consider using `min_const_generics` instead, which is more stable and complete warning: 1 warning emitted